[
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/git/archive/origin-ca-issuer-chart.yaml",
    "content": "---\n# TODO: Once the chart is published use HelmRepository\napiVersion: source.toolkit.fluxcd.io/v1\nkind: GitRepository\nmetadata:\n  name: origin-ca-issuer-chart-git\n  namespace: flux-system\nspec:\n  interval: 10m\n  url: https://github.com/cloudflare/origin-ca-issuer\n  ref:\n    branch: trunk\n  ignore: |\n    # exclude all\n    /*\n    # include charts directory\n    !/deploy/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/actions-runner-controller.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: actions-runner-controller\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://actions-runner-controller.github.io/actions-runner-controller\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/backube-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: backube-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://backube.github.io/helm-charts/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/bitnami-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: bitnami-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.bitnami.com/bitnami\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/cilium-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: cilium-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://helm.cilium.io/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/coredns-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: coredns-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://coredns.github.io/helm\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/crossplane-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: crossplane-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.crossplane.io/stable\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/csi-driver-nfs-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: csi-driver-nfs-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/descheduler-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: descheduler-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kubernetes-sigs.github.io/descheduler\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/emberstack-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: emberstack-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://emberstack.github.io/helm-charts/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/emqx-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: emqx-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://repos.emqx.io/charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/external-dns-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: external-dns-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kubernetes-sigs.github.io/external-dns\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/falco-security-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: falco-security-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://falcosecurity.github.io/charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/flagger-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: flagger-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://flagger.app\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/grafana-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: grafana-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://grafana.github.io/helm-charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/jaegertracing-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: jaegertracing-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://jaegertracing.github.io/helm-charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/jetstack-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: jetstack-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.jetstack.io/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/kiali-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: kiali-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kiali.org/helm-charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/kubefed-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: kubefed-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://raw.githubusercontent.com/kubernetes-sigs/kubefed/master/charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/kubereboot-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: kubereboot-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kubereboot.github.io/charts/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/kubernetes-stable-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: kubernetes-stable-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.helm.sh/stable\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/kyverno-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: kyverno-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kyverno.github.io/kyverno/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/litmuschaos-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: litmuschaos-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://litmuschaos.github.io/litmus-helm/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/mayastor-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: mayastor-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://openebs.github.io/mayastor-extensions/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/metallb-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: metallb-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://metallb.github.io/metallb\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/metrics-server-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: metrics-server-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kubernetes-sigs.github.io/metrics-server\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/node-feature-discovery-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: node-feature-discovery-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kubernetes-sigs.github.io/node-feature-discovery/charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/oauth2-proxy-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: oauth2-proxy-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://oauth2-proxy.github.io/manifests\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/openebs-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: openebs-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://openebs.github.io/openebs\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/openfaas-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: openfaas-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://openfaas.github.io/faas-netes/\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/otel-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: otel-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://open-telemetry.github.io/opentelemetry-helm-charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/postfinance-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: postfinance-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://postfinance.github.io/kubelet-csr-approver\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/rook-ceph.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: rook-ceph\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.rook.io/release\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/sealed-secrets-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: sealed-secrets-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://bitnami-labs.github.io/sealed-secrets\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/secrets-store-csi-driver-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: secrets-store-csi-driver-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/stakater-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: stakater-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://stakater.github.io/stakater-charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/traefik-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: traefik-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://helm.traefik.io/traefik\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/vernemq-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: vernemq-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://vernemq.github.io/docker-vernemq\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/vmware-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: vmware-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://vmware-tanzu.github.io/helm-charts\n"
  },
  {
    "path": ".archive/kubernetes/apps/base/flux-system/repositories/helm/archive/xunholy-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: xunholy-charts\n  namespace: flux-system\nspec:\n  interval: 3m\n  url: https://xunholy.github.io/charts\n  timeout: 3m\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.jsonapiVersion: helm.toolkit.fluxcd.io/v2\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app bazarr\n  namespace: home-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: bazarr\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/bazarr\n              tag: 1.5.6@sha256:79fc37491f55c7e24427bcd669bce3df2d7415ca432a47ce9d53cc5988af8411\n            env:\n              TZ: Australia/Melbourne\n            envFrom:\n              - secretRef:\n                  name: bazarr-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /health\n                    port: &port 6767\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext: &securityContext\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 1Gi\n          subcleaner:\n            image:\n              repository: registry.k8s.io/git-sync/git-sync\n              tag: v4.6.0@sha256:228a26d5f55ac5ae9c51635812570ba0073e0b1e0bd8fc3a653a0523b918c092\n            env:\n              GITSYNC_REPO: https://github.com/KBlixt/subcleaner\n              GITSYNC_REF: master\n              GITSYNC_PERIOD: 24h\n              GITSYNC_ROOT: /subcleaner\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 128Mi\n            securityContext: *securityContext\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: bazarr\n      config-cache:\n        type: emptyDir\n        globalMounts:\n          - path: /config/cache\n      config-log:\n        type: emptyDir\n        globalMounts:\n          - path: /config/log\n      media:\n        type: nfs\n        server: expanse.internal\n        path: /mnt/tank/media\n        globalMounts:\n          - path: /media\n      scripts:\n        type: configMap\n        name: bazarr-scripts\n        defaultMode: 0775\n        globalMounts:\n          - path: /scripts/subcleaner.sh\n            subPath: subcleaner.sh\n            readOnly: true\n      subcleaner:\n        type: emptyDir\n      tmp:\n        type: emptyDir\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: bazarr\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'bazarr.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: bazarr\n          port: 6767\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: home-system\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - ocirepository.yaml\n  - pvc.yaml\n  - secret.enc.age.yaml\n\nconfigMapGenerator:\n  - name: bazarr-scripts\n    namespace: home-system\n    files:\n      - subcleaner.sh=./resources/subcleaner.sh\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: bazarr\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 4.6.2\n  url: oci://ghcr.io/bjw-s-labs/helm/app-template\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: bazarr\n  namespace: home-system\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/app/resources/subcleaner.sh",
    "content": "#!/usr/bin/env bash\n\nprintf \"Cleaning subtitles for '%s' ...\\n\" \"$1\"\npython3 /subcleaner/subcleaner/subcleaner.py \"$1\" -s\n\ncase $1 in\n    *movies*) section=\"1\";;\n    *shows*) section=\"2\";;\nesac\n\nif [[ -n \"$section\" ]]; then\n    printf \"Refreshing Plex section '%s' for '%s' ...\\n\" \"$section\" \"$(dirname \"$1\")\"\n    /usr/bin/curl -I -X GET -G \\\n        --data-urlencode \"path=$(dirname \"$1\")\" \\\n        --data-urlencode \"X-Plex-Token=${PLEX_TOKEN}\" \\\n        --no-progress-meter \\\n            \"http://plex.home-system.svc.cluster.local:32400/library/sections/${section}/refresh\"\nfi\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/app/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: bazarr-secret\n  namespace: home-system\ntype: Opaque\nstringData:\n  PLEX_TOKEN: ENC[AES256_GCM,data:dH2SinyDwDsQ+h10nspxcXemmXI=,iv:6w7IHfDLw5C0gctPWGsM3Mgqt2F34Mt3xoePexq66d0=,tag:vb+DOOM57tL6oqo5zt/NaA==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5VnhsL2ZxY0ppaW53NFBL\n        S0RtaDZ5TUNHZGNjSXExM0FIV05Ma0Q5SEVjCkJldmE5YTFVNWllOHUzd1JMeEpP\n        bEFMOFlISitOZ0lXTHBuZFlaOWRQalUKLS0tIGVsMXg1QkZzb0ptb2ZWaUZiV0pa\n        TmU2TWRFZHFNQ29ZQTJxL012b1ZzZHcKkIRCY6beY1rlDhs49KHLCa2HiSu5J8b7\n        usWq6F+jrdkeYWyN3zjTNrdfJ5isoS4m22y4Cr9JJCmahk1zBiSoUg==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:43:27Z\"\n  mac: ENC[AES256_GCM,data:N9t7RbEcsvowgLnBeIoG3U6IIJ28XMVVHy6vVEmS6ZSVWyQKZf36TSH6fI6eIduftjkDo3WkyyZXMonQCm1nrsCmaT/JEx2zKcbUe6zsRyi7TAfCKl46bSJbR8QC82v36Fhfo3bKH0yUJ/lZpR5gfQo6UPQXh83rnJVBN97C4q8=,iv:Q2GJ50FGfWv1y4qExZAvCqDKQz5nJ4oFSL7Pa1LpdRc=,tag:BA3vB5awv/oSz2J/VmHL2g==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": ".archive/kubernetes/bazarr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: &app bazarr\n  namespace: home-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/home-system/bazarr/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n  targetNamespace: home-system\n"
  },
  {
    "path": ".archive/kubernetes/blocky/app/configs/config.yml",
    "content": "---\n# https://developers.cloudflare.com/1.1.1.1/encryption/dns-over-tls/#how-it-works\nupstream:\n  default:\n    - tcp-tls:one.one.one.one:853\n    - tcp-tls:dns.quad9.net:853\n\nbootstrapDns: tcp+udp:1.1.1.1\n\n# customDNS:\n#   customTTL: 1h\n#   filterUnmappedTypes: true\n#   mapping:\n#     ${CLUSTER_DOMAIN}: ${CLUSTER_LB_COREDNS}\n\n# conditional:\n#   mapping:\n#     cluster.local: 10.96.0.10\n#     ${CLUSTER_DOMAIN}: ${CLUSTER_LB_COREDNS}\n#     .: ${GATEWAY_IP}\n\nblocking:\n  blackLists:\n    suspicious:\n      - https://raw.githubusercontent.com/PolishFiltersTeam/KADhosts/master/KADhosts.txt\n      - https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Spam/hosts\n      - https://v.firebog.net/hosts/static/w3kbl.txt\n    ads:\n      - https://adaway.org/hosts.txt\n      - https://v.firebog.net/hosts/AdguardDNS.txt\n      - https://v.firebog.net/hosts/Admiral.txt\n      - https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt\n      - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt\n      - https://v.firebog.net/hosts/Easylist.txt\n      - https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext\n      - https://raw.githubusercontent.com/FadeMind/hosts.extras/master/UncheckyAds/hosts\n      - https://raw.githubusercontent.com/bigdargon/hostsVN/master/hosts\n    trackers:\n      - https://v.firebog.net/hosts/Easyprivacy.txt\n      - https://v.firebog.net/hosts/Prigent-Ads.txt\n      - https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.2o7Net/hosts\n      - https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt\n      - https://hostfiles.frogeye.fr/firstparty-trackers-hosts.txt\n    misc:\n      - https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20Anti-Malware%20List/AntiMalwareHosts.txt\n      - https://osint.digitalside.it/Threat-Intel/lists/latestdomains.txt\n      - https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt\n      - https://v.firebog.net/hosts/Prigent-Crypto.txt\n      - https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Risk/hosts\n      - https://phishing.army/download/phishing_army_blocklist_extended.txt\n      - https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-malware.txt\n      - https://v.firebog.net/hosts/RPiList-Malware.txt\n      - https://v.firebog.net/hosts/RPiList-Phishing.txt\n      - https://raw.githubusercontent.com/Spam404/lists/master/main-blacklist.txt\n      - https://raw.githubusercontent.com/AssoEchap/stalkerware-indicators/master/generated/hosts\n  whiteLists:\n    suspicious:\n      - https://raw.githubusercontent.com/anudeepND/whitelist/master/domains/whitelist.txt\n    ads:\n      - https://raw.githubusercontent.com/anudeepND/whitelist/master/domains/whitelist.txt\n    trackers:\n      - https://raw.githubusercontent.com/anudeepND/whitelist/master/domains/whitelist.txt\n    misc:\n      - https://raw.githubusercontent.com/anudeepND/whitelist/master/domains/whitelist.txt\n  clientGroupsBlock:\n    default:\n      - suspicious\n      - ads\n      - trackers\n      - misc\n\n# clientLookup:\n#   upstream: ${GATEWAY_IP}\n\ncaching:\n  minTime: 5m\n  prefetching: true\n\nredis:\n  required: true\n  address: redis-master\n  sentinelAddresses:\n    - redis-node-0.redis-headless.databases.svc.cluster.local:26379\n    - redis-node-1.redis-headless.databases.svc.cluster.local:26379\n    - redis-node-2.redis-headless.databases.svc.cluster.local:26379\n\nprometheus:\n  enable: true\n  path: /metrics\n\nhttpPort: 4000\nlogLevel: info\n"
  },
  {
    "path": ".archive/kubernetes/blocky/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.jsonapiVersion: helm.toolkit.fluxcd.io/v2\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app blocky\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    controllers:\n      blocky:\n        replicas: 1\n        strategy: RollingUpdate\n        containers:\n          app:\n            image:\n              repository: ghcr.io/0xerr0r/blocky\n              tag: v0.26\n            env:\n              TZ: Australia/Melbourne\n              HTTP_PORT: &port 4000\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /healthz\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { add: [NET_BIND_SERVICE], drop: [\"ALL\"] }\n              seccompProfile:\n                type: RuntimeDefault\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 128Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: &uid\n        runAsGroup: *uid\n        fsGroup: *uid\n        fsGroupChangePolicy: Always\n        seccompProfile: { type: RuntimeDefault }\n      topologySpreadConstraints:\n        - maxSkew: 1\n          topologyKey: kubernetes.io/hostname\n          whenUnsatisfiable: DoNotSchedule\n          labelSelector:\n            matchLabels:\n              app.kubernetes.io/name: *app\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n      dns:\n        controller: *app\n        type: LoadBalancer\n        annotations:\n          io.cilium/lb-ipam-ips: ${CLUSTER_LB_BLOCKY}\n        ports:\n          dns-tcp:\n            port: &DNSPort 53\n            protocol: TCP\n          dns-udp:\n            port: *DNSPort\n            protocol: UDP\n    serviceMonitor:\n      app:\n        serviceName: *app\n        endpoints:\n          - port: http\n            scheme: http\n            path: /metrics\n            interval: 1m\n            scrapeTimeout: 10s\n"
  },
  {
    "path": ".archive/kubernetes/blocky/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: blocky\n    files:\n      - ./configs/config.yml\n"
  },
  {
    "path": ".archive/kubernetes/blocky/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: blocky\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/blocky/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/cert-manager-csi-driver/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app cert-manager-csi-driver\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: cert-manager-csi-driver\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n"
  },
  {
    "path": ".archive/kubernetes/cert-manager-csi-driver/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: network-system\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/cert-manager-csi-driver/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cert-manager-csi-driver\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/cert-manager-csi-driver/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/cloudflare-ddns/app/deployment.yaml",
    "content": "---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app: cloudflare-ddns\n  name: cloudflare-ddns\n  namespace: network-system\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: cloudflare-ddns\n  template:\n    metadata:\n      annotations:\n        sidecar.istio.io/inject: 'false'\n      labels:\n        app: cloudflare-ddns\n    spec:\n      containers:\n        - env:\n            - name: CF_APITOKEN\n              valueFrom:\n                secretKeyRef:\n                  key: api-token\n                  name: cloudflare-ddns\n            - name: CF_ZONES\n              valueFrom:\n                secretKeyRef:\n                  key: zones\n                  name: cloudflare-ddns\n            - name: CF_HOSTS\n              valueFrom:\n                secretKeyRef:\n                  key: hosts\n                  name: cloudflare-ddns\n            - name: CF_RECORDTYPES\n              valueFrom:\n                secretKeyRef:\n                  key: record-types\n                  name: cloudflare-ddns\n            # https://github.com/docker-hotio/docker-cloudflare-ddns#log-levels\n            - name: LOG_LEVEL\n              value: '3'\n            - name: INTERVAL\n              value: '300'\n          image: ghcr.io/hotio/cloudflareddns:latest\n          name: cloudflare-ddns\n          # Resources allocated based on Robusta KRR output\n          resources:\n            limits:\n              memory: 64Mi\n            requests:\n              cpu: 20m\n              memory: 10Mi\n"
  },
  {
    "path": ".archive/kubernetes/cloudflare-ddns/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - deployment.yaml\n  - secret.enc.yaml\n"
  },
  {
    "path": ".archive/kubernetes/cloudflare-ddns/app/secret.enc.yaml",
    "content": "apiVersion: v1\ndata:\n    api-token: ENC[AES256_GCM,data:d5RH6/yKHPhv0zGikfuG3pdP2Y6ur9Mv6XqOvsMD30v3NxmspWQnGNjBQFrqye4/Yo5WSWghl5A=,iv:tobryj4KN8o9qppDPUjxG9JVvqJl1WZHh5lCoMqSCt4=,tag:QwFTnMMVfJbY/h/Q4wsI0w==,type:str]\n    hosts: ENC[AES256_GCM,data:9yq6mOUZrtG+XDHAqqLkFexrtD5oh6uY,iv:uf/1XBs8fzvYAzf04PHWN2/12MKCRp4JOqIeMjA2/J4=,tag:jNYBkT+A6lZMTYOguR+OKQ==,type:str]\n    record-types: ENC[AES256_GCM,data:XofIqigyWOL1HvMP,iv:4nbLHk9Qki0mmwMIO/+lijx2hyte5HFZh2y5ibMCbEo=,tag:16/OYVoOT6rKKckXCi2tww==,type:str]\n    zones: ENC[AES256_GCM,data:z7baA7qAHRmFTbKcD3+71rTVWFRRnxzz,iv:8LyGmFciAoRp214zSgNOKybqSVImxR751mCCwFusQ00=,tag:1rlS3nv/akKUfFJcQeObFQ==,type:str]\nkind: Secret\nmetadata:\n    creationTimestamp: null\n    name: cloudflare-ddns\n    namespace: network-system\nsops:\n    kms: []\n    gcp_kms: []\n    azure_kv: []\n    hc_vault: []\n    age: []\n    lastmodified: \"2021-09-19T23:59:15Z\"\n    mac: ENC[AES256_GCM,data:R1+ZOUSq4rZIezK9Nr7/gUp3dtOdMyr1/+JAgwV9YvgAJGZkdHgmsAtP/bLsXyEeFRdxYxT5+2Rfw5GjzV3PUAFn5DSc/CwMDhyOj6dUzL+Z218YEb/rGLJI/RJl71e+WWMQ6JQ7h+c7EXWZbHU97KMuomEBHZc6+O990/XLkec=,iv:2umk1CDEimyR5/QrSksrPYO8ZudL6WHSex537lH7hYc=,tag:DsW8h3xKwbQiNUBDYum7Sw==,type:str]\n    pgp:\n        - created_at: \"2021-09-19T23:59:13Z\"\n          enc: |\n            -----BEGIN PGP MESSAGE-----\n\n            hQIMAx42lmLHwoZwAQ/+PigSeQN7F83kI0auxNzhPlixPM/aoQqqbPmLCuCaJK24\n            XLc/iT2diZtN502Q5wbplDEIjfHx8wV0s5c5/Iigx2vCRqxWesRCv+l/PoKIucRU\n            g93kYJHDJEMeopRZSsmY6V0MbZY2n8URfYDkCRXRgjY7SKAm3aKeIzdarOBqISzW\n            abgBMh6i+mCK60XtGPtEEDmrcO0EIpOCsV4OXI+YZ7/M/ktKpg9WJ56k3s/nI0fb\n            x92n5/QifKGwNiPGca1N1/yHUt8O+sbB1juOmnahPvqY0Y6D3rzMTLM7/Iv+/5xR\n            oBd7J+f5OGIhLRc5ZXmUOlQb6JCJrN800lAiZSHvIVqAUILtxFYXoO6njR/prUWW\n            8ibo0mlPE+PJMzeaIWJiR/y0WM6k+Uns8T+PioLS9byK2welCGSN7Un8UPiX77TN\n            huGj/LDLi+1Bp97tIpvT5N50ysWV3LP+0Ga7pDSXUYrUA6qNct3hM7hS86vt5xGD\n            y3DR7BP1dpPNvAlSYE/grWt/vLyX96FRXwFsiJFsR62SJAwod1QV1O+m8gIFrHnz\n            mBeVFljZysAJtChlxBRU1OlX9+ROBQINUs9cYvvsS4WkcNhefj9icE2jFwHx4dqs\n            VdQu3rP3GOIORzZDxFOsQU4yaGOGh18hqiVPItolI87KZgLOxZyJouCJZg72JdHS\n            XgGEgNa6pwu0IUqUQ/16WA0by+Ej9O5LZgKRU2usZHdOt9y/sLGtpYg+N6SDDMzF\n            JfC/dzuz5FYutSuhAm9lScl71ejigKODDMRGoROsjHSYciyQYnJNFkmSh3w0C5E=\n            =frjn\n            -----END PGP MESSAGE-----\n          fp: 0635B8D34037A9453003FB7B93CAA682FF4C9014\n    encrypted_regex: ^(data|stringData)$\n    version: 3.7.1\n"
  },
  {
    "path": ".archive/kubernetes/cloudflare-ddns/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cloudflare-ddns\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/cloudflare-ddns/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/coredns/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app coredns\n  namespace: network-system\nspec:\n  interval: 1h\n  releaseName: coredns\n  chartRef:\n    kind: OCIRepository\n    name: coredns\n    namespace: flux-system\n  dependsOn:\n    - name: cilium\n      namespace: kube-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    # Resources allocated based on Robusta KRR output\n    resources:\n      limits:\n        memory: 128Mi\n      requests:\n        cpu: 24m\n        memory: 128Mi\n    # Custom image bundled with external plugins; currently not in use.\n    # This image is reusable and can be viewed with the available plugins here https://github.com/xUnholy/coredns\n    # image:\n    #   repository: xunholy/coredns\n    #   tag: '1.8.0-rc.7'\n    #   pullPolicy: Always\n    rbac:\n      create: true\n    replicaCount: 1\n    # In this mode CoreDNS is deployed as any kubernetes app in user specified namespace.\n    # The CoreDNS service can be exposed outside the cluster by using using either the NodePort or LoadBalancer type of service.\n    # This mode is chosen by setting isClusterService to false\n    isClusterService: false\n    serviceType: LoadBalancer\n    service:\n      annotations:\n        io.cilium/lb-ipam-ips: ${CLUSTER_LB_COREDNS}\n      externalTrafficPolicy: Cluster\n    # https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#coredns-configmap-options\n    servers:\n      - zones:\n          - zone: .\n            scheme: dns://\n          - zone: raspbernetes.com.\n            scheme: dns://\n        port: 53\n        plugins:\n          - name: log\n          - name: errors\n          # Serves a /health endpoint on :8080, required for livenessProbe\n          - name: health\n            configBlock: |-\n              lameduck 5s\n          # Serves a /ready endpoint on :8181, required for readinessProbe\n          - name: ready\n          # Required to query kubernetes API for data\n          - name: kubernetes\n            parameters: cluster.local in-addr.arpa ip6.arpa\n            configBlock: |-\n              pods insecure\n              fallthrough in-addr.arpa ip6.arpa\n              ttl 30\n          # Serves a /metrics endpoint on :9153, required for serviceMonitor\n          - name: prometheus\n            parameters: 0.0.0.0:9153\n          # Forward everything else to Cloudflare DNS\n          # Note: plugin/forward: this plugin can only be used once per Server Block\n          - name: forward\n            parameters: . 1.1.1.1\n            configBlock: |-\n              except raspbernetes.com *.raspbernetes.com\n          - name: file\n            parameters: /etc/coredns/raspbernetes.db raspbernetes.com\n          # Set up cache\n          - name: cache\n            parameters: 30\n          # Detects simple forwarding loops and halts the CoreDNS process if a loop is found.\n          - name: loop\n          # Allows automatic reload of a changed Corefile.\n          - name: reload\n          # The loadbalance will act as a round-robin DNS load balancer by randomizing the order of A, AAAA, and MX records in the answer.\n          - name: loadbalance\n        prometheus:\n          # Set this to true to create Service for Prometheus metrics\n          service:\n            enabled: true\n          # Disabled due to service monitor resources being created statically to remove chart dependencies.\n          monitor:\n            enabled: false\n    # configure custom zone files as per https://coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/\n    # api.raspbernetes.com - https://www.talos.dev/v1.7/introduction/prodnotes/#dns-records\n    zoneFiles:\n      - filename: raspbernetes.db\n        domain: raspbernetes.com\n        contents: |\n          ${CLUSTER_DOMAIN}.        IN SOA    ns.dns.raspbernetes.com. hostmaster.raspbernetes.com. 1610541154 7200 1800 86400 30\n          ${CLUSTER_DOMAIN}.        IN NS     ns.dns.raspbernetes.com.\n          ${CLUSTER_DOMAIN}.        IN A      ${CLUSTER_LB_ISTIO_INGRESS_GATEWAY}\n          et.${CLUSTER_DOMAIN}.     IN A      ${CLUSTER_LB_NGINX_INGRESS_GATEWAY}\n          api.${CLUSTER_DOMAIN}.    IN A      192.168.50.101\n          api.${CLUSTER_DOMAIN}.    IN A      192.168.50.102\n          api.${CLUSTER_DOMAIN}.    IN A      192.168.50.103\n          *.${CLUSTER_DOMAIN}.      IN CNAME  ${CLUSTER_DOMAIN}.\n          plex.${CLUSTER_DOMAIN}.   IN A      expanse.internal\n"
  },
  {
    "path": ".archive/kubernetes/coredns/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/coredns/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: coredns\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/coredns/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/cross-seed/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: cross-seed\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: cross-seed-secret\n    template:\n      data:\n        config.js: |-\n          function fetchIndexers(baseUrl, apiKey, tag){\n            const buffer = require('child_process').execSync(`curl -fsSL \"$${baseUrl}/api/v1/tag/detail?apikey=$${apiKey}\"`);\n            const response = JSON.parse(buffer.toString('utf8'));\n            const indexerIds = response.filter(t => t.label === tag)[0]?.indexerIds ?? [];\n            const indexers = indexerIds.map(i => `$${baseUrl}/$${i}/api?apikey=$${apiKey}`);\n            console.log(`Loaded $${indexers.length} indexers from Prowlarr`);\n            return indexers;\n          }\n          module.exports = {\n            action: \"inject\",\n            apiKey: \"{{.CROSS_SEED_API_KEY}}\",\n            blockList: [\"category:manual\"],\n            linkCategory: \"cross-seed\",\n            linkDirs: [\"/media/Downloads/qbittorrent/complete/cross-seed\"],\n            linkType: \"hardlink\",\n            matchMode: \"partial\",\n            port: Number(process.env.CROSS_SEED_PORT),\n            skipRecheck: true,\n            radarr: [\"http://radarr.home-system.svc.cluster.local/?apikey={{ .RADARR_API_KEY }}\"],\n            sonarr: [\"http://sonarr.home-system.svc.cluster.local/?apikey={{ .SONARR_API_KEY }}\"],\n            torrentClients: [\"qbittorrent:http://qbittorrent.home-system.svc.cluster.local\"],\n            torznab: fetchIndexers(\"http://prowlarr.home-system.svc.cluster.local\", \"{{.PROWLARR_API_KEY}}\", \"cross-seed\"),\n            useClientTorrents: true\n          };\n  dataFrom:\n    - extract:\n        key: cross-seed\n    - extract:\n        key: prowlarr\n    - extract:\n        key: radarr\n    - extract:\n        key: sonarr\n"
  },
  {
    "path": ".archive/kubernetes/cross-seed/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app cross-seed\n  namespace: home-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: cross-seed\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  dependsOn:\n    - name: qbittorrent\n      namespace: home-system\n  values:\n    controllers:\n      *app :\n        type: statefulset\n        containers:\n          app:\n            image:\n              repository: ghcr.io/cross-seed/cross-seed\n              tag: 6.13.7@sha256:a1fed512261fd968c55cb03c51cff9c6620aa76a34b3b591afca95c890aa8225\n            env:\n              TZ: Australia/Melbourne\n              CROSS_SEED_PORT: &port 80\n            args: [\"daemon\"]\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /api/ping\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 512Mi\n        statefulset:\n          volumeClaimTemplates:\n            - name: config\n              storageClass: ceph-block\n              accessMode: ReadWriteOnce\n              size: 5Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n    service:\n      app:\n        ports:\n          http:\n            port: *port\n    persistence:\n      secret-file:\n        type: secret\n        name: cross-seed-secret\n        globalMounts:\n          - path: /config/config.js\n            subPath: config.js\n      media:\n        type: nfs\n        server: expanse.internal\n        path: /mnt/tank/media\n        globalMounts:\n          - path: /media/Downloads\n            subPath: Downloads\n"
  },
  {
    "path": ".archive/kubernetes/cross-seed/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": ".archive/kubernetes/cross-seed/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: cross-seed\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 4.6.2\n  url: oci://ghcr.io/bjw-s-labs/helm/app-template\n"
  },
  {
    "path": ".archive/kubernetes/cross-seed/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cross-seed\n  namespace: home-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/home-system/cross-seed/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n  targetNamespace: home-system\n"
  },
  {
    "path": ".archive/kubernetes/csi-driver-nfs/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app csi-driver-nfs\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: csi-driver-nfs\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    controller:\n      replicas: 1\n    storageClass:\n      create: true\n      name: nfs-slow\n      parameters:\n        server: expanse.internal\n        share: /mnt/tank/media\n      mountOptions:\n        - nfsvers=4.2\n        - nconnect=16\n        - hard\n        - noatime\n      reclaimPolicy: Delete\n      volumeBindingMode: Immediate\n"
  },
  {
    "path": ".archive/kubernetes/csi-driver-nfs/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: kube-system\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/csi-driver-nfs/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: csi-driver-nfs\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/kube-system/csi-driver-nfs/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: kube-system\n"
  },
  {
    "path": ".archive/kubernetes/emqx/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app emqx\n  namespace: home-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: emqx-operator\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    fullnameOverride: emqx\n    replicaCount: 1\n    image:\n      repository: ghcr.io/emqx/emqx-operator\n"
  },
  {
    "path": ".archive/kubernetes/emqx/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/emqx/cluster/cluster.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/apps.emqx.io/emqx_v2beta1.json\napiVersion: apps.emqx.io/v2beta1\nkind: EMQX\nmetadata:\n  name: emqx\n  namespace: home-system\nspec:\n  image: public.ecr.aws/emqx/emqx:5.8.9\n  config:\n    data: |\n      authentication {\n        backend = \"built_in_database\"\n        mechanism = \"password_based\"\n        password_hash_algorithm {\n            name = \"bcrypt\"\n        }\n        user_id_type = \"username\"\n        bootstrap_file = \"/opt/init-user.json\"\n        bootstrap_type = \"plain\"\n      }\n      authorization {\n        sources = [\n          {\n            type = built_in_database\n            enable = true\n          }\n        ]\n        no_match: \"deny\"\n      }\n  coreTemplate:\n    spec:\n      replicas: 2\n      envFrom:\n        - secretRef:\n            name: emqx-secret\n      extraVolumeMounts:\n        - name: init-user\n          mountPath: /opt/init-user.json\n          subPath: init-user.json\n          readOnly: true\n      extraVolumes:\n        - name: init-user\n          secret:\n            secretName: emqx-init-user-secret\n  listenersServiceTemplate:\n    metadata:\n      annotations:\n        lbipam.cilium.io/ips: ${CLUSTER_LB_EMQX}\n    spec:\n      type: LoadBalancer\n"
  },
  {
    "path": ".archive/kubernetes/emqx/cluster/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: emqx\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'emqx.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: emqx-dashboard\n          port: 18083\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/emqx/cluster/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - cluster.yaml\n  - httproute.yaml\n  - podmonitor.yaml\n  - secret.enc.age.yaml\n"
  },
  {
    "path": ".archive/kubernetes/emqx/cluster/podmonitor.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/podmonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PodMonitor\nmetadata:\n  name: emqx\n  namespace: home-system\nspec:\n  selector:\n    matchLabels:\n      apps.emqx.io/instance: emqx\n      apps.emqx.io/managed-by: emqx-operator\n  podMetricsEndpoints:\n    - port: dashboard\n      path: /api/v5/prometheus/stats\n      relabelings:\n        - action: replace\n          # user-defined cluster name, requires unique\n          replacement: emqx5\n          targetLabel: cluster\n        - action: replace\n          # fix value, don't modify\n          replacement: emqx\n          targetLabel: from\n        - action: replace\n          # fix value, don't modify\n          sourceLabels: ['pod']\n          targetLabel: \"instance\"\n"
  },
  {
    "path": ".archive/kubernetes/emqx/cluster/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: emqx-secret\n  namespace: home-system\ntype: Opaque\nstringData:\n  EMQX_DASHBOARD__DEFAULT_USERNAME: ENC[AES256_GCM,data:ihBafEA=,iv:ZsTN9ZkWbkAkOfJkyQ/85SwQeW2tUXy52lxZvwRU3rY=,tag:LDJoYBZ0FLdi60vYLfjHKQ==,type:str]\n  EMQX_DASHBOARD__DEFAULT_PASSWORD: ENC[AES256_GCM,data:zoqmRZU=,iv:c1mAE/ypSwRT1x8dNLPAfd39y8JV486FAbXpryWv68I=,tag:ZjF14CBmx/tCz7O/Hl+aHg==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxZDdDZS9IYlZJRjJ2aDBm\n        b3QybC82dkdxemtRcGtnaGdCem53dW5yQzF3CnNMV2t3WGRVNll6ckZrcXdPK2Zo\n        YzNUQ1FQSWZwc2xOVXRIWG42ZU5GdjQKLS0tIGw3NDBGYlNaM25ZYytDMXFlRFZ4\n        aHc3U1doVzhodDhleWlYbjlNNXpwSlEKqPoYWY4e3dK8DhJl3JUqJHFbLJ1pI9LC\n        mOGYY84o+4FDg8cPM1JLQQaDYtX91wwZ7QFJBbS17Nk/hbW7L9qLKw==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:43:27Z\"\n  mac: ENC[AES256_GCM,data:fA2cdvaefWGTYM2/B3e71694vvMZvw6lrm9N8jqovz6eKq8D1EmA+ER/xut4BVuU4bqKS+9286j+HVzs88vWM4pTZ6eiNy6lNNqXVpEbGkUiYfAFEdLj5W0IW/3K5AN8VcEQP+/YuDXktph5am4YbUqr6YTkXhk1kFFy5ChWo1A=,iv:Ea+zQloY9kg40Kpxi065HytlwNfC18/hlLBk5PyUUNQ=,tag:loic+lRLpTpn5wKFA0Zn4w==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  name: emqx-init-user-secret\n  namespace: home-system\ntype: Opaque\nstringData:\n  init-user.json: ENC[AES256_GCM,data:7qW1ulUq49TviINOXeMngtqoYxbZM2kNPz6/kp8wN9cZIhsss685cwfLiEOiRAJFfwYplOpujy7fdXaDVBk7Xk1L,iv:b2wIxpECr/TV5uDzLkx4dt9mZAjkQKCDzYOCSN6evPE=,tag:z0G3hi0oCqq8cf8PgvdI5Q==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxZDdDZS9IYlZJRjJ2aDBm\n        b3QybC82dkdxemtRcGtnaGdCem53dW5yQzF3CnNMV2t3WGRVNll6ckZrcXdPK2Zo\n        YzNUQ1FQSWZwc2xOVXRIWG42ZU5GdjQKLS0tIGw3NDBGYlNaM25ZYytDMXFlRFZ4\n        aHc3U1doVzhodDhleWlYbjlNNXpwSlEKqPoYWY4e3dK8DhJl3JUqJHFbLJ1pI9LC\n        mOGYY84o+4FDg8cPM1JLQQaDYtX91wwZ7QFJBbS17Nk/hbW7L9qLKw==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:43:27Z\"\n  mac: ENC[AES256_GCM,data:fA2cdvaefWGTYM2/B3e71694vvMZvw6lrm9N8jqovz6eKq8D1EmA+ER/xut4BVuU4bqKS+9286j+HVzs88vWM4pTZ6eiNy6lNNqXVpEbGkUiYfAFEdLj5W0IW/3K5AN8VcEQP+/YuDXktph5am4YbUqr6YTkXhk1kFFy5ChWo1A=,iv:Ea+zQloY9kg40Kpxi065HytlwNfC18/hlLBk5PyUUNQ=,tag:loic+lRLpTpn5wKFA0Zn4w==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": ".archive/kubernetes/emqx/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: emqx\n  namespace: home-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/home-system/emqx/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: home-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: emqx-cluster\n  namespace: home-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/home-system/emqx/cluster\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: home-system\n"
  },
  {
    "path": ".archive/kubernetes/external-dns-unifi/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: external-dns-unifi\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: external-dns-unifi\n    template:\n      data:\n        UNIFI_API_KEY: \"{{ .UNIFI_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: unifi\n"
  },
  {
    "path": ".archive/kubernetes/external-dns-unifi/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2beta2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app external-dns-unifi\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: external-dns-unifi\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  valuesFrom:\n    - kind: ConfigMap\n      name: external-dns-unifi-values\n"
  },
  {
    "path": ".archive/kubernetes/external-dns-unifi/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: external-dns-unifi-values\n    namespace: network-system\n    files:\n      - values.yaml=./values.yaml\n"
  },
  {
    "path": ".archive/kubernetes/external-dns-unifi/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: external-dns-unifi\n  namespace: network-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.21.1\n  url: oci://ghcr.io/home-operations/charts-mirror/external-dns\n"
  },
  {
    "path": ".archive/kubernetes/external-dns-unifi/app/values.yaml",
    "content": "fullnameOverride: external-dns-unifi\nprovider:\n  name: webhook\n  webhook:\n    image:\n      repository: ghcr.io/kashalls/external-dns-unifi-webhook\n      tag: v0.8.2@sha256:7f0ddbbc83a36a2a9d762e25eef9cafcb3adf0493068a27d72ae71087eafe6f0\n    env:\n      - name: UNIFI_HOST\n        value: https://192.168.1.1\n      - name: UNIFI_API_KEY\n        valueFrom:\n          secretKeyRef:\n            name: &secret external-dns-unifi\n            key: UNIFI_API_KEY\n    livenessProbe:\n      httpGet:\n        path: /healthz\n        port: http-webhook\n      initialDelaySeconds: 10\n      timeoutSeconds: 5\n    readinessProbe:\n      httpGet:\n        path: /readyz\n        port: http-webhook\n      initialDelaySeconds: 10\n      timeoutSeconds: 5\ntriggerLoopOnEvent: true\npolicy: sync\nsources:\n  - crd\n  - istio-virtualservice\ntxtPrefix: k8s.\ndomainFilters:\n  - ${CLUSTER_DOMAIN}\nserviceMonitor:\n  enabled: true\n"
  },
  {
    "path": ".archive/kubernetes/external-dns-unifi/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: external-dns-unifi\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/external-dns-unifi/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/goldilocks/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app goldilocks\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: goldilocks\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n"
  },
  {
    "path": ".archive/kubernetes/goldilocks/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: goldilocks\n  namespace: observability\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'goldilocks.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: goldilocks-dashboard\n          port: 80\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/goldilocks/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": ".archive/kubernetes/goldilocks/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: goldilocks\n  namespace: observability\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/observability/goldilocks/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: istiod\n      namespace: istio-system\n  targetNamespace: observability\n"
  },
  {
    "path": ".archive/kubernetes/istio-csr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app istio-csr\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: cert-manager-istio-csr\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  dependsOn:\n    - name: cert-manager\n      namespace: network-system\n  values:\n    app:\n      certmanager:\n        # -- Don't delete created CertificateRequests once they have been signed.\n        preserveCertificateRequests: false\n        issuer:\n          # -- Issuer name set on created CertificateRequests for both istio-csr's\n          # serving certificate and incoming gRPC CSRs.\n          name: istio-ca\n          # -- Issuer kind set on created CertificateRequests for both istio-csr's\n          # serving certificate and incoming gRPC CSRs.\n          kind: Issuer\n          # -- Issuer group name set on created CertificateRequests for both\n          # istio-csr's serving certificate and incoming gRPC CSRs.\n          group: cert-manager.io\n      tls:\n        # -- An optional file location to a PEM encoded root CA that the root CA\n        # ConfigMap in all namespaces will be populated with. If empty, the CA\n        # returned from cert-manager for the serving certificate will be used.\n        # rootCAFile: /etc/tls/root-cert.pem\n        # rootCAFile: /etc/tls/root-cert.pem\n        # -- The DNS names to request for the server's serving certificate which is\n        # presented to istio-agents. istio-agents must route to istio-csr using one\n        # of these DNS names.\n        certificateDNSNames:\n          - cert-manager-istio-csr.network-system.svc\n      istio:\n        # -- The istio revisions that are currently installed in the cluster.\n        # Changing this field will modify the DNS names that will be requested for\n        # the istiod certificate. The common name for the istiod certificate is\n        # hard coded to the `default` revision DNS name.\n        # Some issuers may require that the common name on certificates match one\n        # of the DNS names. If 1. Your issuer has this constraint, and 2. You are\n        # not using `default` as a revision, add the `default` revision here\n        # anyway. The resulting certificate will include a DNS name that won't be\n        # used, but will pass this constraint.\n        revisions:\n          - default\n          - canary\n    # volumes:\n    #   - name: root-ca\n    #     configMap:\n    #       name: istio-ca-root-cert\n    # volumeMounts:\n    #   - name: root-ca\n    #     mountPath: /etc/tls\n"
  },
  {
    "path": ".archive/kubernetes/istio-csr/app/issuer.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/clusterissuer_v1.json\napiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n  name: selfsigned\nspec:\n  selfSigned: {}\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json\napiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: istio-ca\n  namespace: istio-system\nspec:\n  isCA: true\n  duration: 2160h # 90d\n  secretName: istio-ca\n  commonName: istio-ca\n  subject:\n    organizations:\n    - cluster.local\n  issuerRef:\n    name: selfsigned\n    kind: ClusterIssuer\n    group: cert-manager.io\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/issuer_v1.json\napiVersion: cert-manager.io/v1\nkind: Issuer\nmetadata:\n  name: istio-ca\n  namespace: istio-system\nspec:\n  ca:\n    secretName: istio-ca\n"
  },
  {
    "path": ".archive/kubernetes/istio-csr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - issuer.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-csr/ks.yaml",
    "content": "# TODO: Investigate the best way to enable this through using the helm charts.\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: istio-csr\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/istio-csr/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: cert-manager\n      namespace: network-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/README.md",
    "content": "# Istio\n\n> Note: This is still heavily a WIP\n\nStep 1: Download specific istio version\n\n```bash\ncurl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.5 sh -\n```\n\nStep 2: Generate operator manifests\n\n```bash\nhelm template manifests/charts/istio-operator/ \\\n  --set hub=docker.io/querycapistio \\\n  --set tag=1.6.5 \\\n  --set operatorNamespace=istio-operator \\\n  --set istioNamespace=istio-system\n```\n\nAlternatively install using the following command:\n\n```bash\nistioctl operator init --hub docker.io/querycapistio --tag 1.6.5\n```\n\nStep 3: Apply IstioOperator resource\n\nStep 4: Edit deployments to include `arm64` in affinity\n\n# Canary\n\n```bash\nhelm template manifests/charts/istio-operator/ \\\n  --set hub=docker.io/querycapistio \\\n  --set tag=1.6.5 \\\n  --set operatorNamespace=istio-operator \\\n  --set istioNamespace=istio-system \\\n  --set revision=canary > bla.yaml\n```\n\n## Demo Deployment\n\nA demo application to test Istio sidecar injection\n\n```bash\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app: curl\n  name: curl\n  namespace: test\nspec:\n  progressDeadlineSeconds: 600\n  replicas: 1\n  revisionHistoryLimit: 10\n  selector:\n    matchLabels:\n      app: curl\n  strategy:\n    rollingUpdate:\n      maxSurge: 25%\n      maxUnavailable: 25%\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: curl\n    spec:\n      containers:\n      - image: curlimages/curl\n        imagePullPolicy: Always\n        name: curl\n        resources: {}\n        terminationMessagePath: /dev/termination-log\n        terminationMessagePolicy: File\n        command: [\"sleep\", \"9999999\"]\n      dnsPolicy: ClusterFirst\n      restartPolicy: Always\n      schedulerName: default-scheduler\n      securityContext: {}\n```\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/bedrock-broadcaster/app/certificates.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json\napiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: bedrock-broadcaster-com-le\n  namespace: istio-ingress\nspec:\n  # The secret name where cert-manager should store the signed certificate\n  secretName: bedrock-broadcaster-com-le\n  duration: 2160h0m0s # 90d\n  renewBefore: 360h0m0s # 15d\n  # cert-manager regenerates a new private key on each issuance\n  # https://cert-manager.io/docs/usage/certificate/#rotation-private-key\n  privateKey:\n    rotationPolicy: Always\n    algorithm: RSA\n    encoding: PKCS1\n    size: 2048\n  usages:\n    - server auth\n    - client auth\n  issuerRef:\n    name: letsencrypt-prod\n    kind: ClusterIssuer\n  commonName: ${BEDROCK_BROADCASTER_DOMAIN}\n  dnsNames:\n    - ${BEDROCK_BROADCASTER_DOMAIN}\n    - '*.${BEDROCK_BROADCASTER_DOMAIN}'\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/bedrock-broadcaster/app/gateway.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/networking.istio.io/gateway_v1beta1.json\napiVersion: networking.istio.io/v1beta1\nkind: Gateway\nmetadata:\n  name: bedrock-broadcaster-ingressgateway\n  namespace: istio-ingress\nspec:\n  selector:\n    app: istio-gateway\n  servers:\n    - port:\n        number: 80\n        name: http\n        protocol: HTTP\n      hosts:\n        - '${BEDROCK_BROADCASTER_DOMAIN}'\n        - '*.${BEDROCK_BROADCASTER_DOMAIN}'\n      tls:\n        httpsRedirect: true\n    - port:\n        number: 443\n        name: https\n        protocol: HTTPS\n      hosts:\n        - '${BEDROCK_BROADCASTER_DOMAIN}'\n        - '*.${BEDROCK_BROADCASTER_DOMAIN}'\n      tls:\n        credentialName: bedrock-broadcaster-com-le\n        mode: SIMPLE\n        minProtocolVersion: TLSV1_2\n        maxProtocolVersion: TLSV1_3\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/bedrock-broadcaster/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - certificates.yaml\n  - gateway.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/bedrock-broadcaster/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: bedrock-broadcaster-istio-gateway\n  namespace: istio-ingress\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/istio-ingress/bedrock-broadcaster/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: istio-ingress\n  dependsOn:\n    - name: istiod\n      namespace: istio-system\n    - name: cert-manager\n      namespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/github/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: github\n  namespace: istio-ingress\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - '${CLUSTER_DOMAIN}'\n  rules:\n    - matches:\n        - path:\n            type: Exact\n            value: /\n      filters:\n        - type: URLRewrite\n          urlRewrite:\n            path:\n              type: ReplacePrefixMatch\n              replacePrefixMatch: /k8s-gitops\n            hostname: xunholy.github.io\n      backendRefs:\n        - kind: Service\n          name: xunholy-github-io\n          port: 443\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/github/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - httproute.yaml\n  - service.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/github/service.yaml",
    "content": "---\n# External service definition for xunholy.github.io\napiVersion: v1\nkind: Service\nmetadata:\n  name: xunholy-github-io\n  namespace: istio-ingress\nspec:\n  type: ExternalName\n  externalName: xunholy.github.io\n  ports:\n    - name: https\n      port: 443\n      protocol: TCP\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/istio-gateway/app/authorization-policy.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/security.istio.io/authorizationpolicy_v1beta1.json\napiVersion: security.istio.io/v1beta1\nkind: AuthorizationPolicy\nmetadata:\n  name: ext-authz\n  namespace: istio-system\nspec:\n  # The selector applies to the ingress gateway in the istio-ingress namespace.\n  selector:\n    matchLabels:\n      app: istio-gateway\n  # The action \"CUSTOM\" delegates the access control to an external authorizer, this is different from\n  # the ALLOW/DENY action that enforces the access control right inside the proxy.\n  action: CUSTOM\n  # The provider specifies the name of the external authorizer defined in the meshconfig, which tells where and how to\n  # talk to the external auth service.\n  provider:\n    name: 'oauth2-proxy'\n  # The rule specifies that the access control is triggered only if the request path has the prefix \"/admin/\".\n  # This allows you to easily enable or disable the external authorization based on the requests, avoiding the external\n  # check request if it is not needed.\n  rules:\n    - to:\n        - operation:\n            hosts:\n              - 'sealed-secrets.raspbernetes.com'\n              - 'alert-manager.raspbernetes.com'\n              - 'prometheus.raspbernetes.com'\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/istio-gateway/app/certificates.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json\napiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: raspbernetes-com-le\n  namespace: istio-ingress\nspec:\n  # The secret name where cert-manager should store the signed certificate\n  secretName: raspbernetes-com-le\n  duration: 2160h0m0s # 90d\n  renewBefore: 360h0m0s # 15d\n  # cert-manager regenerates a new private key on each issuance\n  # https://cert-manager.io/docs/usage/certificate/#rotation-private-key\n  privateKey:\n    rotationPolicy: Always\n    algorithm: RSA\n    encoding: PKCS1\n    size: 2048\n  usages:\n    - server auth\n    - client auth\n  issuerRef:\n    name: letsencrypt-prod\n    kind: ClusterIssuer\n  commonName: ${CLUSTER_DOMAIN}\n  dnsNames:\n    - ${CLUSTER_DOMAIN}\n    - '*.${CLUSTER_DOMAIN}'\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/istio-gateway/app/gateway.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/networking.istio.io/gateway_v1beta1.json\napiVersion: networking.istio.io/v1beta1\nkind: Gateway\nmetadata:\n  name: istio-ingressgateway\n  namespace: istio-ingress\nspec:\n  selector:\n    app: istio-gateway\n  servers:\n    - port:\n        number: 80\n        name: http\n        protocol: HTTP\n      hosts:\n        - '${CLUSTER_DOMAIN}'\n        - '*.${CLUSTER_DOMAIN}'\n      tls:\n        httpsRedirect: true\n    - port:\n        number: 443\n        name: https\n        protocol: HTTPS\n      hosts:\n        - '${CLUSTER_DOMAIN}'\n        - '*.${CLUSTER_DOMAIN}'\n      tls:\n        credentialName: raspbernetes-com-le\n        mode: SIMPLE\n        minProtocolVersion: TLSV1_2\n        maxProtocolVersion: TLSV1_3\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/istio-gateway/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: istio-gateway\n  namespace: istio-ingress\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: istio-gateway\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: warn\n  maxHistory: 3\n  values:\n    podDisruptionBudget:\n      minAvailable: 1\n      unhealthyPodEvictionPolicy: AlwaysAllow\n    priorityClassName: \"platform-cluster-critical\"\n    service:\n      annotations:\n        io.cilium/lb-ipam-ips: ${CLUSTER_LB_ISTIO_INGRESS_GATEWAY}\n    affinity:\n      # This podAntiAffinity ensures ingress controllers are not scheduled on the same node\n      podAntiAffinity:\n        requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchExpressions:\n                - key: istio\n                  operator: In\n                  values:\n                    - ingressgateway\n            topologyKey: kubernetes.io/hostname\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/istio-gateway/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - ../../github\n  - authorization-policy.yaml\n  - certificates.yaml\n  - gateway.yaml\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/istio-gateway/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: istio-gateway\n  namespace: istio-ingress\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/istio-ingress/istio-gateway/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: istio-ingress\n  dependsOn:\n    - name: istiod\n      namespace: istio-system\n    - name: cert-manager\n      namespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: istio-ingress\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: istio-ingress\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/plex/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: plex\n  namespace: istio-ingress\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'plex.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - kind: Service\n          name: plex-external\n          port: 32400\n          weight: 100\n---\n# External service definition for Plex\napiVersion: v1\nkind: Service\nmetadata:\n  name: plex-external\n  namespace: istio-ingress\nspec:\n  type: ExternalName\n  externalName: expanse.internal\n  ports:\n    - name: tcp\n      port: 32400\n      protocol: TCP\n"
  },
  {
    "path": ".archive/kubernetes/istio-ingress/plex/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: istio-ingress\n\nresources:\n  - httproute.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/README.md",
    "content": "# Istio\n\n> Note: This is still heavily a WIP\n\nStep 1: Download specific istio version\n\n```bash\ncurl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.5 sh -\n```\n\nStep 2: Generate operator manifests\n\n```bash\nhelm template manifests/charts/istio-operator/ \\\n  --set hub=docker.io/querycapistio \\\n  --set tag=1.6.5 \\\n  --set operatorNamespace=istio-operator \\\n  --set istioNamespace=istio-system\n```\n\nAlternatively install using the following command:\n\n```bash\nistioctl operator init --hub docker.io/querycapistio --tag 1.6.5\n```\n\nStep 3: Apply IstioOperator resource\n\nStep 4: Edit deployments to include `arm64` in affinity\n\n# Canary\n\n```bash\nhelm template manifests/charts/istio-operator/ \\\n  --set hub=docker.io/querycapistio \\\n  --set tag=1.6.5 \\\n  --set operatorNamespace=istio-operator \\\n  --set istioNamespace=istio-system \\\n  --set revision=canary > bla.yaml\n```\n\n## Demo Deployment\n\nA demo application to test Istio sidecar injection\n\n```bash\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app: curl\n  name: curl\n  namespace: test\nspec:\n  progressDeadlineSeconds: 600\n  replicas: 1\n  revisionHistoryLimit: 10\n  selector:\n    matchLabels:\n      app: curl\n  strategy:\n    rollingUpdate:\n      maxSurge: 25%\n      maxUnavailable: 25%\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: curl\n    spec:\n      containers:\n      - image: curlimages/curl\n        imagePullPolicy: Always\n        name: curl\n        resources: {}\n        terminationMessagePath: /dev/termination-log\n        terminationMessagePolicy: File\n        command: [\"sleep\", \"9999999\"]\n      dnsPolicy: ClusterFirst\n      restartPolicy: Always\n      schedulerName: default-scheduler\n      securityContext: {}\n```\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/flagger/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: flagger\n  namespace: istio-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: flagger\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    meshProvider: istio\n    metricsServer: http://kube-prometheus-stack-prometheus.observability.svc.cluster.local:9090\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/flagger/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/flagger/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: flagger\n  namespace: istio-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/istio-system/flagger/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: istio-system\n  dependsOn:\n    - name: istiod\n      namespace: istio-system\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istio-base/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: istio-base\n  namespace: istio-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: istio-base\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: warn\n  maxHistory: 3\n  postRenderers:\n    - kustomize:\n        patches:\n          - target:\n              version: v1\n              kind: ValidatingWebhookConfiguration\n              name: istiod-default-validator\n            patch: |\n              - op: add\n                path: /metadata/annotations/helm.toolkit.fluxcd.io~1driftDetection\n                value: disabled\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istio-base/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istio-base/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: istio-base\n  namespace: istio-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/istio-system/istio-base/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: istio-system\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istio-cni/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: istio-cni\n  namespace: istio-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: istio-cni\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: warn\n  maxHistory: 3\n  # TODO: These resources need more data points to be considered accurate.\n  # values:\n  #   cni:\n  #     # Resources allocated based on Robusta KRR output\n  #     resources:\n  #       requests:\n  #         cpu: 50m\n  #         memory: 512Mi\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istio-cni/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istio-cni/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: istio-cni\n  namespace: istio-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/istio-system/istio-cni/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: istio-system\n  dependsOn:\n    - name: istio-base\n      namespace: istio-system\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istiod/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: istiod\n  namespace: istio-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: istiod\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: warn\n  maxHistory: 3\n  values:\n    pilot:\n      autoscaleEnabled: true\n      autoscaleMin: 1\n      autoscaleMax: 3\n      replicaCount: 1\n      rollingMaxSurge: 100%\n      rollingMaxUnavailable: 25%\n      # Resources allocated based on Robusta KRR output\n      resources:\n        requests:\n          cpu: 100m\n          memory: 500Mi\n    meshConfig:\n      defaultConfig:\n        gatewayTopology:\n          # Always forward the XFCC header in the request, regardless of whether the client connection is mTLS.\n          forwardClientCertDetails: ALWAYS_FORWARD_ONLY\n      accessLogFile: /dev/stdout\n      trustDomain: cluster.local\n      extensionProviders:\n        - name: oauth2-proxy\n          envoyExtAuthzHttp:\n            service: oauth2-proxy.network-system.svc.cluster.local\n            port: 80\n            includeHeadersInCheck: [\"authorization\", \"cookie\"]\n            headersToUpstreamOnAllow:\n              [\n                \"authorization\",\n                \"path\",\n                \"x-auth-request-user\",\n                \"x-auth-request-email\",\n                \"x-auth-request-access-token\",\n              ]\n            headersToDownstreamOnDeny: [\"content-type\", \"set-cookie\"]\n  postRenderers:\n    - kustomize:\n        patches:\n          - target:\n              version: v1\n              kind: ValidatingWebhookConfiguration\n              name: istio-validator-istio-system\n            patch: |\n              - op: add\n                path: /metadata/annotations/helm.toolkit.fluxcd.io~1driftDetection\n                value: disabled\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istiod/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: istio-system\n\nresources:\n  - helmrelease.yaml\n  - podmonitor.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istiod/app/podmonitor.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/podmonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PodMonitor\nmetadata:\n  name: envoy-stats-monitor\n  namespace: istio-system\n  labels:\n    monitoring: istio-proxies\n    release: istio\nspec:\n  selector:\n    matchExpressions:\n    - {key: istio-prometheus-ignore, operator: DoesNotExist}\n  namespaceSelector:\n    any: true\n  jobLabel: envoy-stats\n  podMetricsEndpoints:\n  - path: /stats/prometheus\n    interval: 15s\n    relabelings:\n    - action: keep\n      sourceLabels: [__meta_kubernetes_pod_container_name]\n      regex: \"istio-proxy\"\n    - action: keep\n      sourceLabels: [__meta_kubernetes_pod_annotationpresent_prometheus_io_scrape]\n    - action: replace\n      regex: (\\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})\n      replacement: '[$2]:$1'\n      sourceLabels:\n      - __meta_kubernetes_pod_annotation_prometheus_io_port\n      - __meta_kubernetes_pod_ip\n      targetLabel: __address__\n    - action: replace\n      regex: (\\d+);((([0-9]+?)(\\.|$)){4})\n      replacement: $2:$1\n      sourceLabels:\n      - __meta_kubernetes_pod_annotation_prometheus_io_port\n      - __meta_kubernetes_pod_ip\n      targetLabel: __address__\n    - action: labeldrop\n      regex: \"__meta_kubernetes_pod_label_(.+)\"\n    - sourceLabels: [__meta_kubernetes_namespace]\n      action: replace\n      targetLabel: namespace\n    - sourceLabels: [__meta_kubernetes_pod_name]\n      action: replace\n      targetLabel: pod\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/servicemonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: istio-component-monitor\n  namespace: istio-system\n  labels:\n    monitoring: istio-components\n    release: istio\nspec:\n  jobLabel: istio\n  targetLabels: [app]\n  selector:\n    matchExpressions:\n    - {key: istio, operator: In, values: [pilot]}\n  namespaceSelector:\n    any: true\n  endpoints:\n  - port: http-monitoring\n    interval: 15s\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/istiod/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: istiod\n  namespace: istio-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/istio-system/istiod/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: istio-system\n  dependsOn:\n    - name: istio-cni\n      namespace: istio-system\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: istio-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": ".archive/kubernetes/istio-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: istio-system\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/jaeger/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: jaeger\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: jaeger\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    provisionDataStore:\n      cassandra: false\n    allInOne:\n      enabled: true\n    storage:\n      type: none\n    agent:\n      enabled: false\n    collector:\n      enabled: false\n    query:\n      enabled: false\n"
  },
  {
    "path": ".archive/kubernetes/jaeger/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: jaeger\n  namespace: observability\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'jaeger.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: jaeger-query\n          port: 16686\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/jaeger/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": ".archive/kubernetes/jaeger/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: jaeger\n  namespace: observability\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/observability/jaeger/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: observability\n"
  },
  {
    "path": ".archive/kubernetes/k8s-gateway/app/Corefile",
    "content": ".:1053 {\n  errors\n  log\n  health {\n    lameduck 5s\n  }\n  ready\n  k8s_gateway raspbernetes.com {\n    apex  k8s-gateway.network\n    resources Ingress Service\n    ttl 300\n  }\n  prometheus 0.0.0.0:9153\n  loop\n  reload\n  loadbalance\n}\n"
  },
  {
    "path": ".archive/kubernetes/k8s-gateway/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.jsonapiVersion: helm.toolkit.fluxcd.io/v2\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app k8s-gateway\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    image:\n      repository: quay.io/oriedge/k8s_gateway\n      tag: v0.4.0\n      pullPolicy: IfNotPresent\n    args: [\"-conf\", \"/etc/coredns/Corefile\"]\n    serviceAccount:\n      create: true\n      name: *app\n    service:\n      main:\n        type: LoadBalancer\n        externalTrafficPolicy: Local\n        annotations:\n          io.cilium/lb-ipam-ips: ${CLUSTER_LB_K8S_GATEWAY}\n        ports:\n          http:\n            enabled: false\n          dns:\n            enabled: true\n            port: 53\n            targetPort: 1053\n            protocol: UDP\n    serviceMonitor:\n      main:\n        enabled: true\n        endpoints:\n          - port: metrics\n            scheme: http\n            path: /metrics\n            interval: 1m\n            scrapeTimeout: 10s\n    persistence:\n      config:\n        enabled: true\n        type: configMap\n        name: k8s-gateway-configmap\n        subPath: Corefile\n        mountPath: /etc/coredns/Corefile\n        readOnly: true\n    probes:\n      readiness:\n        custom: true\n        spec:\n          httpGet:\n            path: /ready\n            port: 8181\n            scheme: HTTP\n      liveness:\n        custom: true\n        spec:\n          httpGet:\n            path: /health\n            port: 8080\n            scheme: HTTP\n      startup:\n        custom: true\n        spec:\n          httpGet:\n            path: /ready\n            port: 8181\n            scheme: HTTP\n"
  },
  {
    "path": ".archive/kubernetes/k8s-gateway/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: k8s-gateway-configmap\n    files:\n      - ./Corefile\n"
  },
  {
    "path": ".archive/kubernetes/k8s-gateway/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: k8s-gateway\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/k8s-gateway/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/kiali/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kiali-server\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kiali-server\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  dependsOn:\n    - name: kube-prometheus-stack\n      namespace: observability\n  values:\n    istio_namespace: istio-system\n    # Required as discussed here https://kiali.io/docs/configuration/p8s-jaeger-grafana/\n    external_services:\n      istio:\n        root_namespace: istio-system\n      prometheus:\n        url: \"http://kube-prometheus-stack-prometheus.observability.svc.cluster.local:9090/\"\n      tracing:\n        # Enabled by default. Kiali will anyway fallback to disabled if\n        # Jaeger is unreachable.\n        enabled: true\n        in_cluster_url: 'http://jaeger-query.observability.svc.cluster.local:16685/jaeger'\n        use_grpc: true\n        # Public facing URL of Jaeger\n        url: 'https://jaeger.${CLUSTER_DOMAIN}/jaeger'\n      grafana:\n        enabled: true\n        in_cluster_url: 'http://grafana.observability.svc.cluster.local/'\n        # Public facing URL of Grafana\n        url: 'https://grafana.${CLUSTER_DOMAIN}/grafana'\n"
  },
  {
    "path": ".archive/kubernetes/kiali/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: kiali\n  namespace: observability\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'kiali.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: kiali\n          port: 20001\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/kiali/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": ".archive/kubernetes/kiali/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kiali\n  namespace: observability\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/observability/kiali/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: observability\n"
  },
  {
    "path": ".archive/kubernetes/kubefed/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kubefed\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kubefed\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    # Default values for kubefed.\n    # This is a YAML-formatted file.\n    # Declare variables to be passed into your templates.\n\n    ## Configuration values for kubefed controllermanager deployment.\n    ##\n    controllermanager:\n      controller:\n        repository: kubespheredev\n        image: kubefed\n        tag: v0.8.1-multi-arch\n        imagePullPolicy: IfNotPresent\n        logLevel: 2\n        forceRedeployment: false\n        env: {}\n        resources:\n          limits:\n            memory: 512Mi\n          requests:\n            cpu: 100m\n            memory: 64Mi\n      webhook:\n        repository: kubespheredev\n        image: kubefed\n        tag: v0.8.1-multi-arch\n        imagePullPolicy: IfNotPresent\n        logLevel: 8\n        forceRedeployment: false\n        env: {}\n        resources:\n          limits:\n            memory: 256Mi\n          requests:\n            cpu: 100m\n            memory: 64Mi\n      certManager:\n        enabled: false\n        rootCertificate:\n          organizations: []\n          dnsNames:\n            - ca.webhook.kubefed\n          commonName: ca.webhook.kubefed\n      postInstallJob:\n        repository: bitnami\n        image: kubectl\n        tag: 1.17.16\n        imagePullPolicy: IfNotPresent\n"
  },
  {
    "path": ".archive/kubernetes/kubefed/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/kubefed/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kubefed\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/kube-system/kubefed/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: kube-system\n"
  },
  {
    "path": ".archive/kubernetes/kured/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kured\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kured\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    service:\n      create: true\n    metrics:\n      create: true\n"
  },
  {
    "path": ".archive/kubernetes/kured/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/kured/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kured\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/kube-system/kured/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: kube-system\n"
  },
  {
    "path": ".archive/kubernetes/litmus/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": ".archive/kubernetes/litmus/litmus/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: litmus\n  namespace: litmus\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: litmus\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    portal:\n      server:\n        authServer:\n          env:\n            DEX_SERVER: \"true\"\n            OIDC_ISSUER: \"dex.network-system.svc.cluster.local\"\n            CALLBACK_URL: \"litmus-frontend-service.litmus.svc.cluster.local\"\n"
  },
  {
    "path": ".archive/kubernetes/litmus/litmus/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: chaos-center\n  namespace: litmus\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'chaos-center.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: litmus-frontend-service\n          port: 9091\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/litmus/litmus/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": ".archive/kubernetes/litmus/litmus/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: litmus\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/litmus/litmus/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: istiod\n      namespace: istio-system\n  targetNamespace: litmus\n"
  },
  {
    "path": ".archive/kubernetes/litmus/litmus-core/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: litmus-core\n  namespace: litmus\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: litmus-core\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    nameOverride: \"litmus-core\"\n    fullnameOverride: \"litmus-core\"\n    exporter:\n      enabled: true\n"
  },
  {
    "path": ".archive/kubernetes/litmus/litmus-core/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/litmus/litmus-core/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: litmus-core\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/litmus/litmus-core/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: litmus\n"
  },
  {
    "path": ".archive/kubernetes/litmus/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: litmus\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/loki-stack/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: loki-stack\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: loki-stack\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    loki:\n      enabled: true\n      rbac:\n        pspEnabled: false\n      serviceMonitor:\n        enabled: true\n    promtail:\n      enabled: true\n      serviceMonitor:\n        enabled: true\n    fluent-bit:\n      enabled: false\n    grafana:\n      enabled: false\n    prometheus:\n      enabled: false\n    test_pod:\n      enabled: false\n"
  },
  {
    "path": ".archive/kubernetes/loki-stack/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/loki-stack/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: loki-stack\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/observability/loki-stack/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: observability\n"
  },
  {
    "path": ".archive/kubernetes/metallb/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app metallb\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: metallb\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    prometheus:\n      serviceAccount: \"kube-prometheus-stack-prometheus\"\n      namespace: \"observability\"\n      serviceMonitor:\n        enabled: true\n      prometheusRule:\n        enabled: true\n"
  },
  {
    "path": ".archive/kubernetes/metallb/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/metallb/config/ipaddresspool.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/metallb.io/ipaddresspool_v1beta1.json\napiVersion: metallb.io/v1beta1\nkind: IPAddressPool\nmetadata:\n  name: metallb-l2-pool\n  namespace: network-system\nspec:\n  addresses:\n  - '${CLUSTER_LB_ADDRESSES}'\n  avoidBuggyIPs: true\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/metallb.io/l2advertisement_v1beta1.json\napiVersion: metallb.io/v1beta1\nkind: L2Advertisement\nmetadata:\n  name: metallb-l2\n  namespace: network-system\nspec:\n  ipAddressPools:\n  - metallb-l2-pool\n# ---\n# apiVersion: metallb.io/v1beta1\n# kind: IPAddressPool\n# metadata:\n#   name: metallb-bgp-pool\n#   namespace: network-system\n# spec:\n#   addresses:\n#   - 192.168.50.190/32\n#   avoidBuggyIPs: true\n# ---\n# apiVersion: metallb.io/v1beta1\n# kind: BGPAdvertisement\n# metadata:\n#   name: example\n#   namespace: network-system\n# spec:\n#   ipAddressPools:\n#   - metallb-bgp-pool\n# ---\n# apiVersion: metallb.io/v1beta2\n# kind: BGPPeer\n# metadata:\n#   name: metallb-bgp\n#   namespace: network-system\n# spec:\n#   myASN: 64512\n#   peerASN: 64512\n#   peerAddress: 192.168.50.1\n#   bfdProfile: bfdprofile\n# ---\n# # https://metallb.universe.tf/configuration/#enabling-bfd-support-for-bgp-sessions\n# apiVersion: metallb.io/v1beta1\n# kind: BFDProfile\n# metadata:\n#   name: bfdprofile\n#   namespace: network-system\n# spec:\n#   receiveInterval: 380\n#   transmitInterval: 270\n"
  },
  {
    "path": ".archive/kubernetes/metallb/config/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - ipaddresspool.yaml\n"
  },
  {
    "path": ".archive/kubernetes/metallb/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: metallb\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/metallb/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: network-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: metallb-config\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/network-system/metallb/config\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: metallb\n      namespace: network-system\n  targetNamespace: network-system\n"
  },
  {
    "path": ".archive/kubernetes/node-feature-discovery/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app node-feature-discovery\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: node-feature-discovery\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    master:\n      replicaCount: 1\n    worker:\n      config:\n        core:\n          labelSources: [\"pci\", \"system\", \"usb\"]\n        # TODO: Retest Zigbee USB device\n        # sources:\n        #   usb:\n        #     deviceClassWhitelist:\n        #       - '02'\n        #       - '03'\n        #       - '0e'\n        #       - 'ef'\n        #       - 'fe'\n        #       - 'ff'\n        #     deviceLabelFields:\n        #       - 'class'\n        #       - 'vendor'\n        #       - 'device'\n        #   custom:\n        #     - name: 'zigbee'\n        #       matchOn:\n        #         - usbId:\n        #             class: ['ff']\n        #             vendor: ['1a86']\n        #             device: ['7523']\n    prometheus:\n      enable: true\n"
  },
  {
    "path": ".archive/kubernetes/node-feature-discovery/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  # - networkpolicy.yaml\n"
  },
  {
    "path": ".archive/kubernetes/node-feature-discovery/app/networkpolicy.yaml",
    "content": "---\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  name: node-feature-discovery\n  namespace: network-system\nspec:\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/name: node-feature-discovery\n  policyTypes:\n    - Egress\n  egress:\n    # Egress traffic to kube-apiserver svc\n    - to:\n        - ipBlock:\n            cidr: 10.96.0.1/32\n      ports:\n        - protocol: TCP\n          port: 443\n    # Egress traffic to kube-apiserver endpoints\n    - to:\n        - ipBlock:\n            cidr: 192.168.50.114/32\n        - ipBlock:\n            cidr: 192.168.50.115/32\n        - ipBlock:\n            cidr: 192.168.50.116/32\n      ports:\n        - protocol: TCP\n          port: 6443\n"
  },
  {
    "path": ".archive/kubernetes/node-feature-discovery/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: node-feature-discovery\n  namespace: network-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: network-system\n  path: \"./apps/base/network-system/node-feature-discovery/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/backendtrafficpolicy.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.envoyproxy.io/backendtrafficpolicy_v1alpha1.json\napiVersion: gateway.envoyproxy.io/v1alpha1\nkind: BackendTrafficPolicy\nmetadata:\n  name: openclaw\nspec:\n  targetRefs:\n    - group: gateway.networking.k8s.io\n      kind: HTTPRoute\n      name: openclaw\n  # Compression is intentionally omitted here. Because mergeType is unset, this\n  # route-level policy fully replaces the global gateway-level BackendTrafficPolicy,\n  # effectively disabling Zstd/Brotli/Gzip compression that would buffer SSE/WebSocket\n  # streaming AI responses. If mergeType is ever added, compression will leak back in.\n  timeout:\n    http:\n      # Disable request timeout for long-running AI streaming responses\n      requestTimeout: \"0s\"\n      # Match upstream idle timeout to OpenClaw's llm.idleTimeoutSeconds (300s) and\n      # allow headroom for extended thinking phases (Opus can pause >60s between tokens)\n      connectionIdleTimeout: 3600s\n  # Disable retries - retrying a streaming AI request mid-stream causes\n  # duplicate responses and wasted API usage\n  retry:\n    numRetries: 0\n  tcpKeepalive:\n    probes: 3\n    idleTime: 20m\n    interval: 60s\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/configmap.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: openclaw-config\ndata:\n  openclaw.json: |\n    {\n      \"gateway\": {\n        \"port\": 18789,\n        \"mode\": \"local\",\n        \"bind\": \"lan\",\n        \"trustedProxies\": [\"10.244.0.0/16\", \"10.96.0.0/12\"],\n        \"auth\": {\n          \"mode\": \"token\"\n        },\n        \"controlUi\": {\n          \"allowedOrigins\": [\"https://openclaw.${CLUSTER_DOMAIN}\"],\n          \"dangerouslyDisableDeviceAuth\": true\n        }\n      },\n      \"browser\": {\n        \"enabled\": true\n      },\n      \"agents\": {\n        \"defaults\": {\n          \"workspace\": \"/home/node/.openclaw/workspace\",\n          \"model\": {\n            \"primary\": \"openai/claude-opus-4\",\n            \"fallbacks\": [\n              \"openai/claude-sonnet-4\"\n            ]\n          },\n          \"userTimezone\": \"UTC\",\n          \"timeoutSeconds\": 600,\n          \"maxConcurrent\": 3,\n          \"llm\": {\n            \"idleTimeoutSeconds\": 300\n          },\n          \"contextPruning\": {\n            \"mode\": \"cache-ttl\",\n            \"ttl\": \"1h\",\n            \"keepLastAssistants\": 3,\n            \"softTrimRatio\": 0.3,\n            \"hardClearRatio\": 0.5\n          }\n        },\n        \"list\": [\n          {\n            \"id\": \"main\",\n            \"default\": true,\n            \"identity\": {\n              \"name\": \"OpenClaw\"\n            }\n          }\n        ]\n      },\n      \"session\": {\n        \"scope\": \"per-sender\",\n        \"store\": \"/home/node/.openclaw/sessions\",\n        \"reset\": {\n          \"mode\": \"idle\",\n          \"idleMinutes\": 60\n        },\n        \"maintenance\": {\n          \"mode\": \"enforce\",\n          \"pruneAfter\": \"30d\",\n          \"maxEntries\": 500,\n          \"rotateBytes\": \"10mb\",\n          \"maxDiskBytes\": \"2gb\",\n          \"highWaterBytes\": \"1.6gb\"\n        }\n      },\n      \"logging\": {\n        \"level\": \"info\",\n        \"consoleLevel\": \"info\",\n        \"consoleStyle\": \"compact\",\n        \"redactSensitive\": \"tools\"\n      },\n      \"cron\": {\n        \"enabled\": true,\n        \"maxConcurrentRuns\": 2,\n        \"sessionRetention\": \"24h\"\n      },\n      \"tools\": {\n        \"profile\": \"full\",\n        \"web\": {\n          \"search\": {\n            \"enabled\": true,\n            \"provider\": \"duckduckgo\"\n          },\n          \"fetch\": {\n            \"enabled\": true\n          }\n        }\n      }\n    }\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: openclaw\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: openclaw-secret\n    template:\n      data:\n        ANTHROPIC_API_KEY: \"{{ .ANTHROPIC_API_KEY }}\"\n        OPENAI_API_KEY: \"{{ .OPENAI_API_KEY }}\"\n        OPENCLAW_GATEWAY_TOKEN: \"{{ .OPENCLAW_GATEWAY_TOKEN }}\"\n        OPENCLAW_GATEWAY_PASSWORD: \"{{ .OPENCLAW_GATEWAY_PASSWORD }}\"\n        .credentials.json: \"{{ .CLAUDE_CODE_CREDENTIALS }}\"\n  dataFrom:\n    - extract:\n        key: openclaw\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app openclaw\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        initContainers:\n          install-proxy:\n            image:\n              repository: node\n              tag: 24-slim\n            command: [\"/bin/sh\"]\n            args:\n              - \"-c\"\n              - |\n                export NPM_CONFIG_PREFIX=/opt/proxy\n                npm install -g claude-max-api-proxy@1.0.0 @anthropic-ai/claude-code@2.1.83\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 200m\n                memory: 512Mi\n              limits:\n                memory: 1Gi\n        containers:\n          app:\n            image:\n              repository: ghcr.io/openclaw/openclaw\n              tag: 2026.5.18\n            command: [\"/bin/sh\"]\n            args:\n              - \"-c\"\n              - |\n                exec node dist/index.js gateway --bind lan\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              OPENAI_BASE_URL: http://localhost:3456/v1\n            envFrom:\n              - secretRef:\n                  name: openclaw-secret\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            probes:\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /healthz\n                    port: 18789\n                  initialDelaySeconds: 5\n                  periodSeconds: 5\n                  failureThreshold: 30\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /readyz\n                    port: 18789\n                  periodSeconds: 10\n                  failureThreshold: 3\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /healthz\n                    port: 18789\n                  periodSeconds: 30\n                  failureThreshold: 5\n            resources:\n              requests:\n                cpu: 200m\n                memory: 1Gi\n              limits:\n                memory: 4Gi\n          claude-max-api:\n            image:\n              repository: node\n              tag: 24-slim\n            command: [\"/bin/sh\"]\n            args:\n              - \"-c\"\n              - |\n                export NPM_CONFIG_PREFIX=/opt/proxy\n                export PATH=/opt/proxy/bin:$PATH\n                exec node /opt/proxy/lib/node_modules/claude-max-api-proxy/dist/server/standalone.js\n            env:\n              HOME: /home/node\n              CLAUDE_CONFIG_DIR: /tmp/.claude\n            envFrom:\n              - secretRef:\n                  name: openclaw-secret\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            probes:\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: [\"node\", \"-e\", \"require('http').get('http://127.0.0.1:3456/health',r=>{ process.exit(r.statusCode===200?0:1) }).on('error',()=>process.exit(1))\"]\n                  initialDelaySeconds: 10\n                  periodSeconds: 5\n                  failureThreshold: 30\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: [\"node\", \"-e\", \"require('http').get('http://127.0.0.1:3456/health',r=>{ process.exit(r.statusCode===200?0:1) }).on('error',()=>process.exit(1))\"]\n                  periodSeconds: 10\n                  failureThreshold: 3\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: [\"node\", \"-e\", \"require('http').get('http://127.0.0.1:3456/health',r=>{ process.exit(r.statusCode===200?0:1) }).on('error',()=>process.exit(1))\"]\n                  periodSeconds: 30\n                  failureThreshold: 5\n            resources:\n              requests:\n                cpu: 100m\n                memory: 256Mi\n              limits:\n                memory: 1Gi\n          codeserver:\n            image:\n              repository: ghcr.io/coder/code-server\n              tag: 4.118.0\n            args:\n              - \"--auth\"\n              - \"none\"\n              - \"--user-data-dir\"\n              - \"/home/node/.vscode\"\n              - \"--extensions-dir\"\n              - \"/home/node/.vscode\"\n              - \"--port\"\n              - \"12321\"\n              - \"/home/node/.openclaw/workspace\"\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 1Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            appProtocol: kubernetes.io/ws\n            port: 18789\n          codeserver:\n            port: 12321\n    persistence:\n      data:\n        existingClaim: openclaw-data\n        globalMounts:\n          - path: /home/node/.openclaw\n      config:\n        type: configMap\n        name: openclaw-config\n        globalMounts:\n          - path: /home/node/.openclaw/openclaw.json\n            subPath: openclaw.json\n      proxy-install:\n        type: emptyDir\n        advancedMounts:\n          *app :\n            install-proxy:\n              - path: /opt/proxy\n            claude-max-api:\n              - path: /opt/proxy\n                readOnly: true\n      npm-cache:\n        type: emptyDir\n        advancedMounts:\n          *app :\n            install-proxy:\n              - path: /home/node/.npm\n      tmp:\n        type: emptyDir\n        globalMounts:\n          - path: /tmp\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: openclaw\n  annotations:\n    external-dns.alpha.kubernetes.io/external: \"true\"\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'openclaw.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: openclaw\n          port: 18789\n          weight: 100\n      timeouts:\n        request: \"0s\"\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - externalsecret.yaml\n  - pvc.yaml\n  - configmap.yaml\n  - httproute.yaml\n  - backendtrafficpolicy.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: openclaw-data\nspec:\n  accessModes:\n    - ReadWriteOnce\n  storageClassName: ceph-block\n  resources:\n    requests:\n      storage: 10Gi\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: openclaw\nspec:\n  sourcePVC: openclaw-data\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: openclaw-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: openclaw-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: openclaw-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": ".archive/kubernetes/openclaw/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: openclaw\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/openclaw/app\"\n  wait: false\n  dependsOn:\n    - name: external-secrets\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: openclaw\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/openebs-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": ".archive/kubernetes/openebs-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: openebs-system\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/openebs-system/openebs/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: openebs\n  namespace: openebs-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: openebs\n    namespace: flux-system\n  install:\n    timeout: 30m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    engines:\n      local:\n        lvm:\n          enabled: false\n        zfs:\n          enabled: false\n    mayastor:\n      csi:\n        node:\n          initContainers:\n            enabled: false\n"
  },
  {
    "path": ".archive/kubernetes/openebs-system/openebs/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/openebs-system/openebs/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: openebs\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: openebs-system\n  path: \"./apps/base/openebs-system/openebs/app\"\n  prune: false\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/openfaas/README.md",
    "content": "# OpenFaaS\n"
  },
  {
    "path": ".archive/kubernetes/openfaas/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - namespace.yaml\n#  - networkpolicy.yaml\n"
  },
  {
    "path": ".archive/kubernetes/openfaas/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: openfaas\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/openfaas/networkpolicy.yaml",
    "content": "---\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  name: default-allow-all\n  namespace: openfaas\nspec:\n  podSelector: {}\n  policyTypes:\n    - Ingress\n    - Egress\n  ingress:\n    # Ingress traffic from any pod in current namespace will be allowed\n    - from:\n        - podSelector: {}\n    # Ingress traffic from any pod in the cluster will be allowed\n    - {}\n    # Allow ingress from any endpoint only to any pods but only specific port(s)\n    - from:\n        - ipBlock:\n            cidr: 0.0.0.0/0\n      ports:\n        - port: 443\n  egress:\n    # Egress flows to Kubernetes DNS will be allowed but only specific port(s).\n    - to:\n        - namespaceSelector:\n            matchLabels:\n              kubernetes.io/metadata.name: kube-system\n          podSelector:\n            matchLabels:\n              k8s-app: kube-dns\n      ports:\n        - port: 53\n          protocol: UDP\n        - port: 53\n          protocol: TCP\n    # Egress traffic to any pod in current namespace will be allowed\n    - {}\n    # Egress traffic to any endpoint outside of the cluster will be allowed.\n    - to:\n        - ipBlock:\n            cidr: 0.0.0.0/0\n    # Egress traffic to any pod in current namespace will be allowed\n    - to:\n        - podSelector: {}\n"
  },
  {
    "path": ".archive/kubernetes/openfaas/openfaas/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: openfaas\n  namespace: openfaas\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: openfaas\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    basic_auth: false\n    gateway:\n      directFunctions: true\n    oauth2Plugin:\n      enabled: false\n    operator:\n      create: false\n    prometheus:\n      create: false\n    alertmanager:\n      create: false\n    basicAuthPlugin:\n      replicas: 1\n    ingressOperator:\n      create: false\n"
  },
  {
    "path": ".archive/kubernetes/openfaas/openfaas/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/openfaas/openfaas/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: openfaas\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: openfaas\n  path: \"./apps/base/openfaas/openfaas/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/openfaas-fn/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - namespace.yaml\n#  - networkpolicy.yaml\n"
  },
  {
    "path": ".archive/kubernetes/openfaas-fn/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: openfaas-fn\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/openfaas-fn/networkpolicy.yaml",
    "content": "---\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  name: default-allow-all\n  namespace: openfaas-fn\nspec:\n  podSelector: {}\n  policyTypes:\n    - Ingress\n    - Egress\n  ingress:\n    # Ingress traffic from any pod in current namespace will be allowed\n    - from:\n        - podSelector: {}\n    # Ingress traffic from any pod in the cluster will be allowed\n    - {}\n    # Allow ingress from any endpoint only to any pods but only specific port(s)\n    - from:\n        - ipBlock:\n            cidr: 0.0.0.0/0\n      ports:\n        - port: 443\n  egress:\n    # Egress flows to Kubernetes DNS will be allowed but only specific port(s).\n    - to:\n        - namespaceSelector:\n            matchLabels:\n              kubernetes.io/metadata.name: kube-system\n          podSelector:\n            matchLabels:\n              k8s-app: kube-dns\n      ports:\n        - port: 53\n          protocol: UDP\n        - port: 53\n          protocol: TCP\n    # Egress traffic to any pod in current namespace will be allowed\n    - {}\n    # Egress traffic to any endpoint outside of the cluster will be allowed.\n    - to:\n        - ipBlock:\n            cidr: 0.0.0.0/0\n    # Egress traffic to any pod in current namespace will be allowed\n    - to:\n        - podSelector: {}\n"
  },
  {
    "path": ".archive/kubernetes/origin-ca-issuer/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app origin-ca-issuer\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: origin-ca-issuer\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  dependsOn:\n    - name: cert-manager\n      namespace: network-system\n  values:\n    controller:\n      image:\n        repository: cloudflare/origin-ca-issuer\n        tag: v0.14.1\n"
  },
  {
    "path": ".archive/kubernetes/origin-ca-issuer/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - https://raw.githubusercontent.com/cloudflare/origin-ca-issuer/v0.6.0/deploy/crds/cert-manager.k8s.cloudflare.com_originissuers.yaml\n"
  },
  {
    "path": ".archive/kubernetes/origin-ca-issuer/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: origin-ca-issuer\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: network-system\n  path: \"./apps/base/network-system/origin-ca-issuer/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/plex/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.jsonapiVersion: helm.toolkit.fluxcd.io/v2\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app plex\n  namespace: home-system\nspec:\n  interval: 30m\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/plex\n              tag: 1.43.2.10687@sha256:29aea09831a2b008ffa36b9d71b52aaf1fa3feeedec5f0211c991de01a70f645\n            env:\n              TZ: Australia/Melbourne\n              PLEX_ADVERTISE_URL: https://plex.${CLUSTER_DOMAIN}:443,http://${CLUSTER_LB_PLEX}:32400\n              PLEX_NO_AUTH_NETWORKS: 192.168.50.0/24\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /identity\n                    port: 32400\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 16Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        supplementalGroups: [44]\n        seccompProfile: { type: RuntimeDefault }\n      nodeSelector:\n        intel.feature.node.kubernetes.io/gpu: \"true\"\n    service:\n      app:\n        controller: plex\n        type: LoadBalancer\n        annotations:\n          lbipam.cilium.io/ips: ${CLUSTER_LB_PLEX}\n        ports:\n          http:\n            port: 32400\n    persistence:\n      config:\n        # existingClaim: plex\n        # TODO: If setting up Plex for the first time, you'll want to add the globalMounts section\n        type: emptyDir\n        globalMounts:\n          - path: /config/Library/Application Support/Plex Media Server\n      # Separate PVC for cache to avoid backing up cache files\n      cache:\n        type: emptyDir\n        globalMounts:\n          - path: /config/Library/Application Support/Plex Media Server/Cache\n      logs:\n        type: emptyDir\n        globalMounts:\n          - path: /config/Library/Application Support/Plex Media Server/Logs\n      tmp:\n        type: emptyDir\n      transcode:\n        type: emptyDir\n      media:\n        type: nfs\n        server: expanse.internal\n        path: /mnt/tank/media\n        globalMounts:\n          - path: /media\n            readOnly: true\n"
  },
  {
    "path": ".archive/kubernetes/plex/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: plex\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'plex.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: plex\n          port: 32400\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/plex/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": ".archive/kubernetes/plex/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: plex\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: home-system\n  path: \"./apps/base/home-system/plex/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/reloader/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app reloader\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: reloader\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    reloader:\n      readOnlyRootFileSystem: true\n"
  },
  {
    "path": ".archive/kubernetes/reloader/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/reloader/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: reloader\n  namespace: kube-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: kube-system\n  path: \"./apps/base/kube-system/reloader/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/sealed-secrets/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: sealed-secrets\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: sealed-secrets\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    networkPolicy:\n      enabled: true\n    metrics:\n      serviceMonitor:\n        enabled: true\n"
  },
  {
    "path": ".archive/kubernetes/sealed-secrets/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: sealed-secrets\n  namespace: kube-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'sealed-secrets.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: sealed-secrets\n          port: 8080\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/sealed-secrets/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": ".archive/kubernetes/sealed-secrets/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: sealed-secrets\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: kube-system\n  path: \"./apps/base/kube-system/sealed-secrets/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: istiod\n      namespace: istio-system\n"
  },
  {
    "path": ".archive/kubernetes/secret-store-csi-driver/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: secret-store-csi-driver\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: secret-store-csi-driver\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    logFormatJSON: true\n    ## Install RBAC roles and bindings required for K8S Secrets syncing if true\n    syncSecret:\n      enabled: true\n    ## Enable secret rotation feature [alpha]\n    enableSecretRotation: true\n"
  },
  {
    "path": ".archive/kubernetes/secret-store-csi-driver/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/secret-store-csi-driver/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: secret-store-csi-driver\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: kube-system\n  path: \"./apps/base/kube-system/secret-store-csi-driver/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/snmp-exporter/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app snmp-exporter\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: snmp-exporter\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  dependsOn:\n    - name: kube-prometheus-stack\n      namespace: observability\n  values:\n    fullnameOverride: *app\n"
  },
  {
    "path": ".archive/kubernetes/snmp-exporter/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: observability\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/snmp-exporter/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: snmp-exporter\n  namespace: observability\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: observability\n  path: \"./apps/base/observability/snmp-exporter/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/speedtest/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.jsonapiVersion: helm.toolkit.fluxcd.io/v2\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: speedtest\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    image:\n      repository: ghcr.io/miguelndecarvalho/speedtest-exporter\n      tag: v3.5.4\n    resources:\n      requests:\n        cpu: 15m\n        memory: 64M\n      limits:\n        memory: 128M\n    service:\n      main:\n        ports:\n          http:\n            enabled: false\n          metrics:\n            enabled: true\n            protocol: TCP\n            port: 9798\n"
  },
  {
    "path": ".archive/kubernetes/speedtest/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/speedtest/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: speedtest\n  namespace: observability\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  targetNamespace: observability\n  path: \"./apps/base/observability/speedtest/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/tf-controller/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: tf-controller\n  namespace: flux-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: tf-controller\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    affinity:\n      nodeAffinity:\n        requiredDuringSchedulingIgnoredDuringExecution:\n          nodeSelectorTerms:\n          - matchExpressions:\n            - key: beta.kubernetes.io/arch\n              operator: In\n              values:\n              - amd64\n"
  },
  {
    "path": ".archive/kubernetes/tf-controller/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/tf-controller/ks.yaml",
    "content": "---\n# Note: Arm64 support is currently not supported https://github.com/weaveworks/tf-controller/issues/453\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: tf-controller\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/flux-system/tf-controller/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: flux-system\n"
  },
  {
    "path": ".archive/kubernetes/tf-controller/terraform/gcp/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: gcp-creds\n  namespace: flux-system\ndata:\n  key: ENC[AES256_GCM,data:qdGhNr5VLi+zCbeBzVwXo+ppH3wjWw6GJLHVDAfR0PFoD4yWi4B70tFiRTVujZDX1bariGS70e9L+HzI3q3LtZsMa3p/68HjPrEtLhjUxm7HiSpep0bJMbwhc/um+FZ3v4inoMK24UC54QP+nr0qXhqww3HYvqtkD7w2QriekYsfM0q8KgprZubvx6ZoAKUbSUKHsuUmSDL+79AfTV7pmQImU6eUawsJHGGkaoHybhJzT/fxrUlktV2fduY9Sf04wotGGQJ2SdeOlLAJonF1oquzGUfTUiO9cYiA69kM1oRn2VhF/OQIvfvG6ExkxvbGJP0jyEftlSF/F567RILI7PTRfIf8DIf8qN47TSzu3mbvMBcDLKPO5JzTuK6Vry+xcx7GsVouUvhSMaB3UkzxgkbhSXNfk9QR6M2m8RpIIBpbyWUECwH6xbCfAinSYGhgwIN18fOjdkmdXp9olwbfge+ksyH69ONNVvOzoA36gFeSD6MlXjOXKohXe7VQXzEkpdm3bP7dmVVAyBxHd7aBfcjNroPBuhgeFNtj4uG3GgKaB0MI+gHwx5kdXPzhywVHnDqgsRyZ6ru5FsGzX/aeIvtnSNd5Okp7Mm+YbZvF8JvBa6IRaMXRjE0VMuET3LnN0fYs8W9ChvPHD3ZLXeGBrzmM2UBAi55HMqtrrMKXY9ahVXDIxrkoFKxIkSEqw1Q3DeI4MJKQoKE8h1U73Jy2liUwiPl4sPC5HiFsR7cu2LkaD1YM9j4ps/edYHZjl7uSPBk2HgGXP6SaMoYRM1ZlgfXIGbJx74+8gm3gl6Db01KCJALIhcJ6sw8z/AZBMmO8lmxrV4iTYU9VaJjiYnZXGTgFZlrr56Z8PVbTok+PE0A08YRLPouBwuW2eSkhmwGSdX/Qp4End9sGseURYJf+LDPMdqaTBmW8KTZJ+3MgOXcJYKOQmjG5QCkP1CQDacVVyaBFGKELEHr0wD2bwVzokluC2z3OPEOvTbaE/kMlCXafTwq08fgN6pvNrqam1DXrEq1O4X3TZE3qfJagePYWg/tF+nbmA1HrZyNvO8IwHreaNA2BhX+MQDOJ9Qumu++7F9oIzwahv9eoSZJCeFynOcooEIEt4RW6GeZE2GGmFGsexGWbeeL1eXoS5SW8cs+Z7JF+kNmwABHyXnAPDKU1Z1GYQ+FMmqPVLWtaQU7u5In8DwrwhUbzsKaBzIAslwtEUJDA/6CTbUMfvYbY7J3EfwyssXun0Wl+SkEWEWHkwybQQvSWn2mjM7XWAfNk9iA9XBVBnnHwZG97Zjq6ozWnyw++Zi3/EFTyrrGiQNyqMZa5UHGgumVd2ArLCsoNZR8jdwYKfJJ/6KGutrJEosaJ1TUiNE9UHKX/4PA0qz7c27t71JhqckDJNtZd7ShXXlmLWO6cGuCtMeasFpOD7W8USEppC+JEOMtE+mQ9qdgLMu49z+FWuDl8w0dun8ZZxBlhv9ePIwZiGOnXnS2t7EQeSO8FEoTiKXwgfZOLt8hs8sFPF55Xz6GwaGytakuFniFpZru/cUM6DFh6lYy+2xrwznJ3rVSZYTf/zXO2YhjUY53v5EptOKgICaZKGgZ14KPNT9eH3j+YrGuCCinxDk3UKUTIz0UGtVaYp+g6bxTcNqYOgeAHaStbqh3eqvfyboSRrPFipH6HpEJgVVWuPF3b2UOjIO4m1Hj4F9gQ20SKoeKg8ZzTTrA6iMgPwICZ95aMpS425MrCzZYjInaWYeT9bGNBcGhbAJgHnkHWooMgW3+0OrXEJMM/rkLdCt3iFifp+lbhg6i1VZ22p0IDIhtybfCJpiJJdIaeTVEhU2xi4xbF0w2ZKb/p6eR+LUm9mlmbrXZMhauMG9gMCLqXPUrihX+v5TiauAB4Wu8/tQdS7SfHhc79xunCcvWI9c/NijMKgJOvRMjo/eNQDKvV9kWhNhj5IuIzh7i1XKRtQzIx1CM/uBfzd04DF2RdMUKguc1L9ryyUMnBGF8ly0xTfhciOU25tCk9MaPoSOyPEYy1nBu+80LS5sl7PnrrEEPGGBr5+hvU90UEY+62zINnrpPb3bkdTtkwOuna/j2tNCsgu31AomMXTFdWzDzgZhvXZ82I0Tvg+9YS2NO9MV5BglAfczBhRKSjY/AdoCp2kylk4k0ybdTNjAhqLpoinorKBT3/x9r1uvspxhhCnmk7preQzyVUkFqRw5WIT5eKvVb3tO6RN8rl6wVzsEtrTZJMHmQrHNu6G9w8/e4ildA2pFVhIBJH/Dq3A8ZV5BaYHfsclLqRfdsPJPBqCPvr+s3I66JDjKi2XmWa58htYPPN8iOuFxvrCszHoaRMksSl9EU11QVMUtfYCe6jEhJKp6xeetolhlgbQKvoIrOUXcXfOAF00IqyspCNwVXNeSvlMbKkpt7BP3qncITpCqiAyTYTC/cgS+nuk9LAoGkcr9XIqXaeZ0hdQBHKB4B7Au9//803aN+KFO5dBrcbaKpE1QyZrqVt6YLOEGrcNWAVmndBHL9MPM6KwJgWFePe+H8thfGqHKl6z18/cEeVYNG8A9vXpkmIDb82FxbsL5ZnfXKBZQoNnT8Vc21mITBsaqL0/F4rMMTle0Q9ws9TVa6ObKhf3U+B65QjwhycQedA/2yI+62eDvbSwI9t6yZBtiTJklRQXGyN+SJdnbRrf1rU+jKzSa5aefGw+yCq+JHRCv7/yXHfMLtT99k1mFsXBSpBOVu39I/6Sq36srCFija6uQAirdIy0XRWjEWQ5WqB/wef53wYuB2Xlx2J6+Gg7+rI8PW2COc6gnfB87LQM9VPfuuEKjTlXc09UkL0xzTCW1wXZgxBkXqHDecdjALgHvA4kkGMTZmX0lgvbLxZ2Z6ntRWZdf37ZED4E5+OTnW5w/3jfOoeQCbXYr0GQBWjd+iZzBFL4G0YXjmioDBuRyZkTSp944LiaiRgwryIYPqg0mlFa/OLCRN+XfIpTqmG378GQbrVFaqNLRbjHo3a5Qzeq6cIt1cXL/n47HPT8OMKM0oJXaP62/bfWWpXoDEpxNttc84tWh/ahS4SsSFQqtP03bohxwRG6zDXHH8JMV5JRU6heeV2q6/sGF2Hw79Yi/OnmWQl9O1fbQ5VSH9e3Ewh5rvI18ig3ZcXoXtUiqInlvNMJaLq/SKuDptYEyW3J3s+BU3Kjro7V9rrLn3g8kawjjN5ghrXfa84Jc0tvCoMSRF7toxaHNhFSIwiNkXSdVUOQVOyyXd72AdHr6Q94JF0/Z8oC6JaL/f4XyGLWyBtxn5lAG1Kq3F38eA5X1RsjOYZaMCqg07VmqEWOldqvFtelNQMUmv5u+zGRxeasVt3r1UPF2/cppCLo1qLitblDgzCAG+Nud2RR9C/KiC4O6M82G6VXt5akpkXbmBmSPY9dfHBPi4dcD7P6BXanZnmUFA1xaD4/6gNzco33IVaH+lDkF18hLZQf26TgrH7OTc7us/vytmCNkTfjMErASzKLyGBsSLpPhjkpcMRfURg47DIF8n8UoJOZzAF/gvBJjCye8YdFIQ0ZDJlLJ68rBcEAc5EzfQzh1Ipkz7N7GYfhs9L5TD0VCxzV6wyMi1InexmSwPfha15ULnbZ7qbs0REsDEYE6lkOWJJqd1WeMKJkU4/mqDu4+Y3EXWmKpEVsLBd+ZpkzqK+MPH5OHjzjR9nFjoVeYFes+vcPRE3Vs+fpEaxc5XccdAHYYkraihh3biM2N1KFSyqRAcscK5I7d80lF8gR6fS0Yf4wBeH7/RSFqBgLYX1mxGsYHDb75Kn3aa+t0cZRMpCQ8asbhilJ/AXgsM65AjaasSTR3SZUqwrMlkI9x4iVrHUuqWNM8tXlPP3fZ3SsyKmWAsokrPBSBIiMZOszfDSb/tCmL4+lajXkPl9YToB+yBe8t2Sgd2ED/eGQmE4I4kTK9CHj2P0LfMyMxq9STnmd5TCzvnqVE1GLfXf5uRbrSBHFtwUtW+KdGvgycYPAAnjrQhOcNTplHwMAvpzCNc238OUuILJnI6/oswzI8hwyiYImbR/AaKxpxcaGhjN3nIUc2+aE/YidWU8tIJQc049vSeKjEv1egMTWrejMd6rrFEPjhgdN2O20uM=,iv:GqDvJ/YmQ3d5UWclUb45nWT29fxBd/UFKA6dNZYW/tM=,tag:KZF6B10+fA69KRfgpJJEmw==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaMUplWU5qaCtnTFZQUFRq\n        T0xRWWFuMmlqemt6YSswdCs1WnVrQlVIMGpNCndwQ3QweXRUb09TQjhTQ01wTldn\n        djZzRXAwMU9kYmhRL1hmVDFlcVpIYUUKLS0tIHZ1YXF6RXVManZJMHVZK1FJV3d2\n        cG56R1VxS2JWVzViZkQrNjNUMEZ0Mk0KeFmBCFu3ZMXo0gU+3hK+AGvQzo0GOcLB\n        JboZWaQRDbETJR9YL3k+Lyg6S7+7ab2wHuayRrEAN3l7rvvfqxSkAA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:43:27Z\"\n  mac: ENC[AES256_GCM,data:1AjpdP2JMhQAD5hby0FaTmX4P3wnwAFUd1od7I18hfqI8MJ39VITpvH8eEMBs8CBKnrLQ0cDTcmxj/sVpBKFKIzjJ3g11ZY/9U3/W4g3xKdZcIA3gmDwmLGh7X8WNtRmGmCIygs2I4jBCD+ZIILw5GEmXgAlzO1rjgPBiGpPil8=,iv:PlFJtVew4s4Sf8eVRvCQbg0XhpCy1bQnkE3tUo1iH5g=,tag:Dz9fA6KajDrYgOrHEJ2hEQ==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": ".archive/kubernetes/tf-controller/terraform/gcp/terraform.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/infra.contrib.fluxcd.io/terraform_v1alpha1.json\napiVersion: infra.contrib.fluxcd.io/v1alpha1\nkind: Terraform\nmetadata:\n  name: storage\n  namespace: flux-system\nspec:\n  interval: 12h\n  path: ./terraform\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  runnerPodTemplate:\n    spec:\n      env:\n        - name: GOOGLE_APPLICATION_CREDENTIALS\n          valueFrom:\n            secretKeyRef:\n              name: gcp-creds\n              key: key\n      affinity:\n        nodeAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            nodeSelectorTerms:\n              - matchExpressions:\n                  - key: beta.kubernetes.io/arch\n                    operator: In\n                    values:\n                      - amd64\n"
  },
  {
    "path": ".archive/kubernetes/thanos/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: thanos\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: thanos\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    image:\n      repository: thanosio/thanos\n      tag: v0.41.0\n    queryFrontend:\n      enabled: false\n    query:\n      replicaCount: 3\n      podAntiAffinityPreset: hard\n      replicaLabel:\n        - __replica__\n      dnsDiscovery:\n        sidecarsService: kube-prometheus-stack-thanos-discovery\n        sidecarsNamespace: observability\n    # TODO: Re-enable once OpenEBS is configured on Talos\n    compactor:\n      enabled: false\n    metrics:\n      enabled: true\n    serviceMonitor:\n      enabled: true\n    objstoreConfig:\n      type: GCS\n      config:\n        bucket: 'thanos-raspbernetes-storage'\n  valuesFrom:\n    - kind: Secret\n      name: thanos-objstore-config\n"
  },
  {
    "path": ".archive/kubernetes/thanos/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: thanos\n  namespace: observability\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'thanos.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: thanos-query\n          port: 9090\n          weight: 100\n"
  },
  {
    "path": ".archive/kubernetes/thanos/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - secret.enc.age.yaml\n"
  },
  {
    "path": ".archive/kubernetes/thanos/app/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: thanos-objstore-config\n  namespace: observability\ndata:\n  values.yaml: ENC[AES256_GCM,data:ZgEeR/6rpXeRz1EvAH7D4WX7CXL6z2zLWqmU4T4qfa/qVyRJTvVaRL+EmbbSsKlsDQ4+gSHpWg6aEUVz2I9qmuDfgb0aSfGNk55G3OMqv9d0c3D8/HmuiCBjFASn2e1VRMdhoD/PyhKVZR+HpNJVG5ZxZtwRpKfgRcF/EFgUNPW88lkhucEIoo6nrF7A9vQgkIbQ9Mw+EJGSayGIz96juPLY7etvMvRNKlxV9zG3WJxnack3iAQsj6a7K6M8gbhDycYnpdGCzNDcxHz481qLmWUGPArf3fS67hRU/NAJRHf2XicH2dkfL7IosddISGGusRTUA2DpRkvm3WuorGeE70Q3gFav4pKwz4SLekdKT3lxubVUHj9tmcwSCkuixi4DJWxXMEQr25i1Q0xNV1YcFsX7NYqwgLK3NujACIyHIBAa2lDEjoWZGe1qwDqZf63ZJvVIwfL9gZXI3JmP31AaZqdUX9kXatQP6cUs8MH7Se4B9pniqv7anbjxngsrhcjt+JI+alPQPRcBHSQWNik0Gg25TgyjS7dLx9g39TRy5RxtQpRhvjvri3ARb+GlUqKC+PohvvhnUTYNdqpKWB51B2+zngW/guLWlRYkq+wpEbu3quvjRnrOlfHVm0zrEMmIQFKS+tAc0Z99qC+Ai7N1cqmIqEDOhbBvn0+P+bA+XuzPaGHYCC3aK4MbruMiWl30e/pnjOxVI/1OpDgRghLPe4Mo3p3urwXT2Be42O2QvRkg3sz05pwLNcK9XvFpRQOoLvYAOLAsCva3WuytuHvxP6JDSeIsbTNTWeGz10KoOcZp2u6j4mrE+zHBxCxl2zkXhRVngueukee6cTRpLbJwfAzR2tvjswCN9UI1pJ9zmutuQbUrjbbuYxa1OC7BLBpBhMNRGL8LkwvZ7aFJa8Bp/L6Z5M3tr+T9tDibbLGNLKNXHhIwQ2eowUkRSegGZjT1zooolz5fNyINJeXZjw1p+PEQ08zHI4LxHUrEz/eII1ipeoRsukGvu5H9Ry+6vPXf7qE2ILR1G+yg+uIzh9bHnC4t1OIIo4udTOes5tQCdgNWFN/0GnCXHFt24pZ9hhovCukbiMTBiuA8/iUeyFa+G4Ott/jwz++1MjiwXAaVZ9Y6sxqpBbEbVLJ7liUJUZArQFxhJaECBMrhB5/A2Ce2VB0a7/zrDeHaFOPFIdoRDKUBjpia6VZl99QkSCDj6InzxsoOR1G0EjXEZ1FuNisB948kjh2hW1TFzU9wR+/EFQCWxaT7+rKNjjclpQto/3vlwl2V4qBwU0qAQgKrI/aUdDh7LpU2ml8toFj7aE/eLTFg6H0IEfFxGpaUeTTvCraqEWhiS5aePCB2g0xoqEQRIXoiXixnKsqVhar3KhlLgRTR0vRpcRtSAsrCPzbqZ1DdoErajzrhuslzyH2tflmoUtGA2/7soD3ut5ubQGoK7t7zEOfH2YmQcWbf5/9BCFXXXXxqFIiQ47TNpj1eIZ1n+2ZpfqDn4EIp6P6uRUWCSQf6YGbK3aBfdp6clys+4icPQeeEJO/1omlz3Vnm7cInP9vcnrU7kr/EJFyUiNtQANJ940KCTOk9gaDYcUSoxiLS3tSjYAahnIjJH/g53t88bMAhlV3vxVWfvveZA2svOyvGdiytDRbQtfoiRnQhB9fIOSuuQiICzaHTCrQrraifBsqZRehdRZ3yBSJqbpZUTeb5HlBpyaYBJxwT1CEyq+iMqyf6HK48T2EeGd88NN+ZpZbY/CP7wvLI4OCUqs6OqndY+DZU96RQO+9DI8BCtktDWXnbCJYUk/jWmoVSaYqq+hiSWp869r/M/0Owhn7o6q54H6/raT1sGUVu5ncla032EnmpRcU/r1gJ/ttoBaxO3R/mgdl/S7uKDQswJK/VeacxNd0aPNBAyY9Xf483spDuvoNOPirZ1XQuSy0VwQOFBvEm9w040dYYwnqLX7UxwKt3Jylzjd7FmibLGdJt6ZktV6UzA+X5tA65o+yz0j5m8GuiYHvTUDJoTenYlOK7eLJ4Sud6ynWHeUEoBbUVPHcu5n77F8Gwp7JUYFOfUAZRF2XABMjCljBs3VxsJfjkEq/34Ls3OIW2YYLPBxTtrCEnAuRIXk51eSDvrS62ndCZjyvetriM5ZPB1vW7gKtwRhyzi3iWCLDKPdp1/LQDN4WryfLTK+Dylh4SCGjdv8i5+x92eJNMk0IAdCiNaMrpcyN+SH32ias1h/sCGZzvm7ivxdyyCF/PuCNrj+dFtVZ7rtbaI6zbLsV5zgCdF+ccm/dGFdhPzsQT2f5fvOv2oaj1sM7aNrndwfOzhy5YnAlXtkZrVAleNd31CKywbD3UnukTct97pAjTXf6tcZ5OCeVlpRvAcybeMXvm8f0qq6TWgSslKRJ87Xa+I2abad43W5r0yduFiWQRVB81BzhPmiMqZbWf8HQSy3EZRZTOqxAZj1sl5LMUMuAyVw3rxxmfsX5YWfNOlCuqgcSbpCYqRB5D0UpFuCcvo5PYMpgdcrm8NEOSOFN2gVRKEPYO3sqOTGmMDBIK6ZTuMwd7NN9ED+bm5N7DmC0ci0Ubvj4YFbOVwU4pBRZejJs/nFS3D6dM4JTOaYdWnFfp6upYhpSzy+ysOurIocl2v0HTv2c0jlWvioFEh+HgDNzxQVK1gzn4WiGpBHE/t3vGHRb5NPz54TXSTPnfDe36sYzjNlNgWBrDuKNKSepLkfjHUpbZqVUPW6R9ltJ6Vm42TlqKEXA2F3ZGG1N0beDdSszTxmKZsohgHTDb8XZQzhs7bhiqVe2FMIwl9LMhj9hOVxLNgvVSfv9ynwDOzFVIb00lw7awco8h9ZCshJmY7X5zUtL9nrIYktj5Yl30u7sndYAeHufC4+q47cWYzYVFJ+xJcE09jEGlVrxQy0QEvU6+0y0JAEvljd5BvqvMewtZ0+fD6Hn0lGP5jSxmmjGmhfRIfB+TkEvdNkGlxI6bBWYx+mtDlBuMt4/qdNx+D9/WPxjOdPfm+bNAt36Z+JVeM2QDUJxOmeiJngIM/Jm7ZQImtvvgN9k/bGp36fOho10odZ/8ukJ09fx4bHTn8JqiB25VVEXBtxr3cLIffqsUAdDgfNki/OOg1Ccf7XXzvF7OZzQU3x2dzNGrRtU1r84ycE4hEu7xJm6laIEIAF8l6XTZW0sbtjx2bOuErC0WfG0UTwipvFt26SL++2ReRufDNs5A3o12Fdgcmk7C8p05oSgDMKm2tqDOKiYJGJmsbojAfuSM1YITiSOruGc7aUMQ2gH4qERA2w4YZOT01ZHETCtJNLkiTOVx0eOxdh8DSaBq6uE2eaJVURbar4PspoBym1XNdnku+YQrdlv1y5ahFYJh+JzgoDfGOXD7CZBVLh2Hvi7jtj8lO+c5edLWsDvinZLpsei0acSG5NC4IQMdZz4YYiuM/EGKD2EL3+kuSNYH1WAamwIMYKxRz7ItYPz2l1pPnpzSp283hhr2leklPL8w5WpXpmKLiho//Rbm+RKmep7B4c682ty2QIOaOPbfEACaRhCeBYSiQFHIh5O3hvFolI9FWPGlNBwvlJaNiXszgzycZBuhoBntcaLtDdAvrM1e/C6yfxxuZZ+j64/LZ8YDxcm9QmUxM0cUnm/CiJJT2Ks1hpEXjI33ILpduEjRXlK9vaurWvGMh3zOiMnUdfcUm7LEtFny7qT7Z8f6mefOfcFmGkAX+EdA/1XcPj+2zV0dmD5TakhJLE5hKIr8be5ECuYdR7HQY+xHUPTTtBiFB8GSCZGKUtxj3YNwJB7vEz10UE3EAvkwUGF8q01rvURiSr4fEv/O5owItd/lpBYtj2ciH7d1V518yvo+/H0VSsb+fbsfdOoSEnD6zjABgS2TWEGtOKzxEclkC9/2LEdJpb9YX548yqT9JEY5uiBxqyoL5dLADQvZ4wCj0zZSXWLFaWqTzCUmgnBCqpMpPh1t3cyBTWhQ8ovP5ThzKlD/OSvjZK+Abw9H6fQU3oug+cRFyaliSApL9Np9SD4qvTlO+0q3/Iy+JnnFCTHxIoTCxzbzH7d59Xfx81uiAgqkLp8xn/KrX+FJHxFtM0uVOhuaHjNkhWnnSfFlzgiTDW3JPfteYK1VMN7MSclxFajOlwYnr8JuJ0OQsM4jnV7GKOezgBnAESXrCNFgeKs1/lAE0V0YXzD37d4vVCiPFiLkGi22yGIMYkwTr/fes7jT+m3A1QQxfFvatHEPdWd3OqkbiBkDAn0BjV0SRSbsba7/Krnc21r7ZWM6d9YExJpTwCrjt0bkYAlk71Qkmqykxg5Kz836YcwJlbpYaA==,iv:nCNui8aF2uHeg3/8u5OPIR6kbxTz9khRz0Fa5JGpmu0=,tag:FtwpNID7fp67UQZdfO5JUA==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1QllRbktLampSbFp5OXpV\n        RWJES2pQZDJ6MGlFaDVQSmtlRDhwUkUxSjFzClBlRzA4L0duc2JiWFhIVHBQQ290\n        ZFY4NWh4TVdxSzFrQ1M1Vzh2V0VrYmcKLS0tIGFQTTNZSldGeFJBMkppTjZlNjhr\n        MEN6bnE5a2NGWUladXAwYWhNWjZrdzgKOuSYD9Vxwq5wrzHzaOnfpWG1ywGb9b+g\n        6Ee9jlkLjqmL+O6HJwKmhxLBpJ3kDPtQpitof2wOhza5sWRBho2ltA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:43:27Z\"\n  mac: ENC[AES256_GCM,data:OGGLV9DK9wyr6KA3+vEd1ONgxKkCVndosu82brHriHQT/TIFggQqquX09u+6IscNxhNv+7k1Z/p1Bryz2+f4QyHkSQSES0gF+w3bZQN4z226ct8b1w3SEt91PfkO5ZKbxCCV3zwT9JrsXlLQj1tNuIFkwOk4a8iD0/a6DGMtiNM=,iv:1Lc9MaSd7A0Vt7PhT5BmRESeAZAUGRa0iF5wwSJzbU4=,tag:R/b8A62o9B0doE0Ligyn1Q==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": ".archive/kubernetes/thanos/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: thanos\n  namespace: observability\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/observability/thanos/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: observability\n  dependsOn:\n    - name: istiod\n      namespace: istio-system\n"
  },
  {
    "path": ".archive/kubernetes/traefik-ingress/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": ".archive/kubernetes/traefik-ingress/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: traefik-ingress\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/traefik-ingress/traefik/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: traefik\n  namespace: traefik-ingress\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: traefik\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  dependsOn:\n    - name: cert-manager\n      namespace: network-system\n  values:\n    deployment:\n      enabled: true\n      replicas: 1\n    service:\n      annotations:\n        io.cilium/lb-ipam-ips: ${CLUSTER_LB_TRAEFIK_GATEWAY}\n      spec:\n        externalTrafficPolicy: Local\n    autoscaling:\n      enabled: true\n      minReplicas: 1\n      maxReplicas: 3\n    logs:\n      general:\n        format: json\n        level: INFO\n      access:\n        enabled: true\n        format: json\n    ingressClass:\n      enabled: true\n      isDefaultClass: false\n      fallbackApiVersion: v1\n    tlsOptions:\n      default:\n        minVersion: VersionTLS12\n        maxVersion: VersionTLS13\n        sniStrict: true\n    pilot:\n      enabled: false\n    experimental:\n      plugins:\n        enabled: true\n    providers:\n      kubernetesCRD:\n        enabled: true\n        allowCrossNamespace: true\n        allowExternalNameServices: true\n    resources:\n      requests:\n        memory: 128Mi\n        cpu: 100m\n      limits:\n        memory: 512Mi\n"
  },
  {
    "path": ".archive/kubernetes/traefik-ingress/traefik/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": ".archive/kubernetes/traefik-ingress/traefik/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: traefik\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/traefik-ingress/traefik/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: traefik-ingress\n"
  },
  {
    "path": ".archive/kubernetes/velero/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": ".archive/kubernetes/velero/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: velero\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": ".archive/kubernetes/velero/velero/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: velero\n  namespace: velero\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: velero\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    # Resources allocated based on Robusta KRR output\n    resources:\n      requests:\n        cpu: 100m\n        memory: 128Mi\n      limits:\n        memory: 256Mi\n    # Init containers to add to the Velero deployment's pod spec. At least one plugin provider image is required.\n    initContainers:\n      - name: velero-plugin-for-gcp\n        image: velero/velero-plugin-for-gcp:v1.14.1@sha256:b92b9cc55947eb7e570c47643b37dc8de99686dfdf912a08c1462aa10f53e2f5\n        imagePullPolicy: IfNotPresent\n        volumeMounts:\n          - mountPath: /target\n            name: plugins\n      - name: velero-plugin-for-openebs\n        image: openebs/velero-plugin:3.6.0\n        imagePullPolicy: IfNotPresent\n        volumeMounts:\n          - mountPath: /target\n            name: plugins\n    # Disable updateCRDs using the velero image\n    # Upstream bitnami/kubectl doesn't support ARM64 images\n    upgradeCRDs: false\n    # Info about the secret to be used by the Velero deployment, which\n    # should contain credentials for the cloud provider IAM account you've\n    # set up for Velero.\n    credentials:\n      # Name of a pre-existing secret (if any) in the Velero namespace\n      # that should be used to get IAM account credentials. Optional.\n      existingSecret: cloud-credentials\n    # Parameters for the `default` BackupStorageLocation and VolumeSnapshotLocation,\n    # and additional server settings.\n    configuration:\n      # Parameters for the `default` BackupStorageLocation. See\n      # https://velero.io/docs/v1.5/api-types/backupstoragelocation/\n      backupStorageLocation:\n        - name: default\n          provider: gcp\n          bucket: raspbernetes-velero-backups\n    # Backup schedules to create.\n    schedules:\n      daily-backup:\n        schedule: \"0 6 * * *\"\n        template:\n          ttl: \"120h\"\n  postRenderers:\n    - kustomize:\n        patches:\n          - target:\n              kind: BackupStorageLocation\n              name: default\n            patch: |\n              - op: add\n                path: /metadata/annotations/meta.helm.sh~1release-name\n                value: velero\n              - op: add\n                path: /metadata/annotations/meta.helm.sh~1release-namespace\n                value: velero\n"
  },
  {
    "path": ".archive/kubernetes/velero/velero/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - secret.enc.age.yaml\n"
  },
  {
    "path": ".archive/kubernetes/velero/velero/app/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: cloud-credentials\n  namespace: velero\ndata:\n  cloud: ENC[AES256_GCM,data:VGVj5ZuzhFqQZ+aUZ3cjkPjGw/J0ASclWErxTwhFAVoSGX902bOJ8X9Qw72hWr1EYReoZNJ60IEE0Q7YyfRn2XnOb89glteFvUeL2eZD5Wup94pCcwIgHXbf/XTrNsfKaSOHD/ioqQXgZ+AnSA14eVauf+fwjz3NKiRkx9rB7ik48Y+vnal6/4WeX07eQe/EAdJ0ZHb5CD2RcbC1Dy0EXowxk8dFMq8S0Jop56COf3PrBdaMzkvz4xgtRC4t8KxuVyW/GC68ZaOxYo4AMC5/KapmcCEHTQdXsv7eo5bf0b2tXCgUO/LVKM3ZVUcYmpmmClM2cRnDg5M0oRrsNAbdPDm5/lFRe8XNgNiPhxZ5dhcs1P4cza9nljjLFHtsvzjF9YqpQrmjmHvSKBHs9YbL16owK49uc2/TmQDjVsaMDEKhah0Y7D/2185XNUz1Jypw0VsTVFr/BgZOpQXAaipez5oUQmE5VQw3UcyYIkzXLGqEl1lNKorCB9uA/6nyYPnBemHwhtAovXCODGeR+eq8uWXRyZ9Cb0PCdDWJhooD957p2PY+K2hZU8RFlqFokpgAmi/grfxVAmAcIIQ7840Gdx/ICTaUN8g/K4YLFzdSGzocNGCcivMIbqev4Oc8M0aalt36UD/TLcqM3fvq45I3K+olMzwrJCct27MHv9NHZjkfdwgDzAUT1PdUO7FNnKFFL+JHh8pUXhzdSsC1NW90bMM/Q1M8hkTMj4PX42N7a4/Nen3UUb3x5IzTjS1y5P9z3MBQB1ns8V73FvGlDt5p/iggAAuZd9Jy1+WMmdkIbY3+3KZl6m4EVh2xp/5mw4xJUX/xeTZl2kyuYw66kQufyvE4BW4Vc+QtRHoCiTNkkHdRm4Ycv01wNl7OOkqVv8mKo1cJNEVyjwTHsvbv31oAa/6UVbn3Meb2lAUv2lH2+qTTdFIGJzehwtxQkeOPR8Wffe6m+CuN9xJ/8dF80T8HnU4P6nX0UgrHIserPW9V6BKExVdzsKc3cGn3dWYZDsvbqozw6BxvjcMYY51gNfhIf7MS6PwxDzilJND4T5+pN6d0RyvG094liR/CdtVRrw5GnEwlv4Nn6Z5a3WENhnrErQKO//PeHGiiVb6Cni2SFibJBv4gm53MC6TqOUi4iXzD6ghntEvoRq4gtEUlhpXOhd6yJjQ3mTk4KMak1iYS0oqRUumy1j9pNsYxPMiu65WU7LEi3Zu5xxkF7OmpDL6PMCH/NEz/92QX5OXyjNooTV+p9GTzs8SfuXgqRF5AGG4WnhUM4Oop9rsaOhz74l9Ln9BtX2olEDAvPKazu9bQoCle6AnmloZ/qXr0A2ZcTVTVksrg15oR00iLVkny/PON9duaE89wNJtVh360RiyTJuR8sAU0TB5lmHrmwaDtjG0dZ0kWePwHwUkSr5B6/4K5xKi8KE8Q5wdApGTpI8JjvjTkD19aFFfu4vTUJ14/2q2byLzvzj+EjzHt1dr5hkQb25JHolIFWPQLQI28YlPJBkU9OdGaJiVtCLAwIOOMX7Y8yrPRQN29Jn0SvafQoSAYG65RmPyGHF8o6UzwtzY1b8oJaFrM/A3X8h9BL1xYR6/cxanQLZ1IDLDXvmBtvdt1gcRKNNYytDT0M7BzGS/eRgddoPh5qr+KGTHBHTYWph8hltdv4UC6zgcRCaY3O4oCSNnLiruc6mHORHwtVq7ydCgaj3JKW6fwHVybPpgpvROc65YA6ozqNknYzRNfx+jU6gPFaCEPUa/yEFkIyIHjhA6hem0XmRzjU2E03laFFp8agTUX463V949zjiA6UQxLimn/87H3YRMwZJ7Rs5m2+hYQH4bOSNSGYlowuXkNYzyAelkmDFD5k9sMBnFJITxFrGDoP6lRHrjAEFN0NC3ibJmy8Z8S4quRO9trOczzl9lDOJpIGm1SRRymOQg7CDM76Z3SWHVw0psfh6iNCf91mtl4JEuigRfIUhxURaIcb33w9KM5m/eEzQdLrreMcp8L/2erRZyJhkg85AE2nBWp/iBaJX6bSJUg6100AmyFkEVoYHQBt/q782hACQWx5wf5zf8i4uL5Woi48aHODgd7dF5mNCJXcxILwImfO7oktRQGbgmClIZ4iETYheFcsNgteNK0+lzKVSCCD5iFrKseIFA3fvxxWdG8WXJe8AZ6Dop8/+ohYdzP7v1V9tsa9Fvqhe6xYhoPOwF9DTK6Fcpbq5HTI3MNS7/r1J4e1QRUg+2lQNYhUgaTpS7HmTOT54klKomugx+UhDCnRuI8I0feKg7seVrJEP23on3Fl+JYwiZJMiYAaAdEI6RjbjbQaoQJkrEMWfmUmmcTRTgXaFG59MOpK9K6D3v2MyYDlGSE5ME2xJgEEX5UPLjhItj+cL17j+x2SBnpi1RvvqrDdER+NtZlM8Sv91oESUNE4cH+UzfMGFjKqPZ1S4Xf5pC5esP0vtb4aOqf/xL2fZo9rzuqxlWk/VxADDKOP8lzgfvZErfNtjqCopA2md1gsnevvHxElH+99ow2y2W5qOh6wefwc3EjjSQMqbh4uJMtyKG6yTmqcYThwwto+4yLu4l3jacV2WO30PHPCHPZf4W7I8SIVdcxBB9oHxf5Jq8mNKa5uh8J65fmb5cLBN25NVqBZc+iPfsPU1GvrFmIUlXsR2CtWIlt9CTuujhqxP6MOIldYY7ZPoDfPApf2PL4V2WgTZ7g+0YNefpvjJVqWeDYXIdOsDcK6s2gbY9q4C/bQttj/z0spWsLFa7cdn4bNY3dCmKAl7C0Mjnpr4dYkDQ/ailxZbZYVTHm4KooV5uLAUNRRPL+fVVq2sf7+9Og6JzvR2NW3CoCejTstaZpgVXv/xcqLwb/B6YHe2JFpk+zXvEZIlllqt6z/SdhJPHKE6yayczW/kruXdyP2n7xW2V+yVoLfGQd4a6fAC0k4+85Dsk10KLX5F4RW23xc5iqC5jqPtqCWi2l60lP0DK+S3R+zAxaEq2QNoHwjwwqARfer9w8vx6DteO1qUCjt/K2wNQd0kTxMCFDAlBySpWlZKCqq2YXLuoo2IF7+zlQuDq0lGUh12Gj7ULqfvtALl9JpBpuB9SCDjznTuh/iJlDFeR7JyaPB1BFqpqerrmDzz0S3/q84KcMxvulprKyoJ9qq9B8RrQHdIt3WU2eR0Tvav8ugG9gnI67dyaKVEPQEqjwImotbIVTGyDI7ZXOM2lJtJwmagLjGUaEFwecmaBSFQlvgWF4ZsXj3dUD6jBfV/7kFdSY7fOPlIWGaHIQBwy5Ot4scsV5FY5wviwM8DnTlYkUkcLwfeMMo4tpg9CLasG5DUJGcbynFabwzklftjiZKSAuIFnWePloWVq+vWJCLbQHqYKsOl+L+4oDW6uFvddHfQJPh6WRQiQCe5z3JN4v3d6Trk0f3jbUI01ml7oXOC4YwnVbMBrNzglSgxHeUCIqU7kOEANgVfVVT2laaT1KztfRj2DNEmDxKhn+T6EqFEzmr4oO1O8Lem9OLxnolRXdi6b+fFIytJVjfuXof7H50OPuy1jN0G8NjjeuK7QGsD+q3EnOOcxc2jZfIlvq6B61TjJ27ENCr58YXknK62T6717aLu7jmqQDpyyQzOa/JSrgbBIZRbeE3AIHT+x8vJzcr56ucMB9ZT6p65t1OWiZr6R578iWYJSgQmZv7v9/HRBJWBPpkGBlnqvWDaanhjX6D43IW8HIWFmcWirehIETfU3Llg3yID1lJVLbsjWTlVhRF9+UK6adG4CAcHrqFprCpzuUO0IizQz6tVlqPg9hNz+gjFLUIbRFTMkpQMTaM5ZB4MKvrUl7oZxD6Z6vwdmMmsNGDguBhU29IANA8hTfOx/OaJmXvMjhsuObVgqiP+yoDiBey8DCSWpVBEkV27To6T0IBs+8PlxXCUb22+jp7APPwlUsJ9hi4kD0Mpf7M63ag+Yf2v+wHhP1plj6VZkV1lSsfA3HHnG4U8+GmQ/bt3IiCA0/iNLg8rjCq5PgxIYveI7sIK8UyfEy1n7f2y0pUtTe3j2owQ9SKrZ3qgwhEx7F5ZFSJIUOajEuuapucmibWX2+LAWBQbTUIkTAiBYsxfBtNOOn,iv:Un7Jm8IihNb1irOtGpfYTJLRZPtW/qEmDs3dEV0E2kE=,tag:bwZQ7/6DHwvPpN0z7UA5cw==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRUDNaazM0dm5Pc25HWkVy\n        SHphZGd6MHh4eFdXS2JkRXpIR1RnOXJXU1M0CmpiKzlYcHhRZkFHaC9KdGl2d3Yy\n        bkREZ0dva3U2TTZ5RGFOa1dQYmpDTzQKLS0tIDVrWmRubmtCTjVGMzAxQzRaWm5P\n        WXRuTkUwUjI1Wno1VXNTTkttOEt3ZmsK1Fb/pr9i4uwHjsBJb1FR1kbHcgSky5f4\n        ug0n2v0el4MYUvEh9BrWQY7FkB78p1OsQVHo0gsRsiE/l4c3UbHVRQ==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:43:27Z\"\n  mac: ENC[AES256_GCM,data:1ZDxHHqd9RpOjlZKSDM5RQ/KtywK6f0uiQexNTFKQqVhKBNNP9zklcIXFsv98NLEZp19+aO7NDZVc+lRNr8neYczr/ugOvgZjD2WFfYJPKtBgS7vaPBOAydZaZdFkTmrzxLWXGrdprHCt1KA9wpS5uZH+hkoAnLd9mkgj6KK+Po=,iv:Cqf7PUwyuVg72ZBZ6bL2Cx8sB2EiGQZyaqWUSu4uV/s=,tag:esI9hD7XLMZthA0CDC9kiw==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": ".archive/kubernetes/velero/velero/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: velero\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./apps/base/velero/velero/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: velero\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/README.md",
    "content": "# VMaNGOS - Vanilla WoW Server (1.12.1)\n\n## Server Configuration\n\n- `mangosd.conf` and `realmd.conf` are managed as ConfigMaps in the HelmRelease\n- The realm address is set via `VMANGOS_REALMLIST_ADDRESS` env var on the database container\n- Game settings (player limit, max level, etc.) are in `mangosd.conf`\n\n## Managing Users\n\nAccounts are managed via the mangosd server console. Attach to the running pod:\n\n```bash\nkubectl attach -it -n game-servers deploy/vmangos-mangosd -c app\n```\n\n### Creating an Account\n\nIn the mangos console:\n\n```\naccount create <username> <password>\n```\n\n### Granting GM Privileges\n\n```\naccount set gmlevel <username> 3\n```\n\nTo detach from the console, press `Ctrl+P` then `Ctrl+Q`.\n\n## Account Registration\n\nA web-based registration page is available at `https://emberstone.owncloud.ai`. Players can create accounts without needing console access. The registration page is deployed separately in `vmangos-registration/`.\n\n## Connecting\n\n### Requirements\n\n- World of Warcraft **1.12.1** client (patch 5875)\n- An account on the server\n\n### Client Setup\n\n1. Edit `WoW/Data/enUS/realmlist.wtf` (or `enGB`):\n   ```\n   set realmlist wow.owncloud.ai\n   ```\n2. Launch WoW and log in\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/dnsendpoint.yaml",
    "content": "---\napiVersion: externaldns.k8s.io/v1alpha1\nkind: DNSEndpoint\nmetadata:\n  name: vmangos-wow\n  annotations:\n    external-dns.alpha.kubernetes.io/external: \"true\"\nspec:\n  endpoints:\n    - dnsName: \"wow.${CLUSTER_DOMAIN}\"\n      recordType: A\n      targets:\n        - \"${EXTERNAL_IP}\"\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: vmangos\n  namespace: game-servers\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  values:\n    controllers:\n      database:\n        containers:\n          app:\n            image:\n              repository: ghcr.io/mserajnik/vmangos-database\n              tag: latest\n            env:\n              TZ: Australia/Melbourne\n              MARIADB_USER: mangos\n              MARIADB_PASSWORD: mangos\n              MARIADB_ROOT_PASSWORD: password\n              VMANGOS_REALMLIST_NAME: Emberstone\n              VMANGOS_REALMLIST_ADDRESS: ${CLUSTER_LB_ENVOY_EXT_GATEWAY_API}\n              VMANGOS_REALMLIST_PORT: \"8085\"\n              VMANGOS_REALMLIST_ICON: \"1\"\n              VMANGOS_REALMLIST_TIMEZONE: \"0\"\n              VMANGOS_REALMLIST_ALLOWED_SECURITY_LEVEL: \"0\"\n              VMANGOS_ENABLE_AUTOMATIC_WORLD_DB_CORRECTIONS: \"1\"\n              VMANGOS_PROCESS_CUSTOM_SQL: \"1\"\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['healthcheck.sh', '--connect', '--innodb_initialized']\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['healthcheck.sh', '--connect', '--innodb_initialized']\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['healthcheck.sh', '--connect', '--innodb_initialized']\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 2Gi\n      realmd:\n        initContainers:\n          wait-db:\n            image:\n              repository: busybox\n              tag: latest\n            command: ['sh', '-c', 'until nc -z vmangos-database 3306; do sleep 2; done']\n        containers:\n          app:\n            image:\n              repository: ghcr.io/mserajnik/vmangos-server\n              tag: \"5875\"\n            command: [\"realmd\"]\n            env:\n              TZ: Australia/Melbourne\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 5\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 10m\n                memory: 64Mi\n              limits:\n                memory: 256Mi\n      mangosd:\n        pod:\n          terminationGracePeriodSeconds: 120\n        initContainers:\n          wait-db:\n            image:\n              repository: busybox\n              tag: latest\n            command: ['sh', '-c', 'until nc -z vmangos-database 3306; do sleep 2; done']\n        containers:\n          app:\n            image:\n              repository: ghcr.io/mserajnik/vmangos-server\n              tag: \"5875\"\n            command: [\"mangosd\"]\n            tty: true\n            stdin: true\n            env:\n              TZ: Australia/Melbourne\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 500m\n                memory: 1Gi\n              limits:\n                memory: 4Gi\n    service:\n      database:\n        controller: database\n        ports:\n          mysql:\n            port: 3306\n      auth:\n        controller: realmd\n        ports:\n          auth:\n            port: 3724\n      world:\n        controller: mangosd\n        ports:\n          world:\n            port: 8085\n      soap:\n        controller: mangosd\n        ports:\n          soap:\n            port: 7878\n    configMaps:\n      mangosd-config:\n        data:\n          mangosd.conf: |\n            DataDir = \"/opt/vmangos/storage/data\"\n            LogsDir = \"/opt/vmangos/storage/logs\"\n            HonorDir = \"/opt/vmangos/storage/honor\"\n            LoginDatabase.Info = \"vmangos-database;3306;mangos;mangos;realmd\"\n            WorldDatabase.Info = \"vmangos-database;3306;mangos;mangos;mangos\"\n            CharacterDatabase.Info = \"vmangos-database;3306;mangos;mangos;characters\"\n            LogsDatabase.Info = \"vmangos-database;3306;mangos;mangos;logs\"\n            RealmID = 1\n            WorldServerPort = 8085\n            BindIP = \"0.0.0.0\"\n            WowPatch = 10\n            PlayerLimit = 100\n            MaxPlayerLevel = 60\n            CharactersPerRealm = 10\n            WorldAvailable = 1\n            Anticheat.Enable = 0\n            Rate.XP.Kill = 3\n            Rate.XP.Quest = 3\n            Rate.XP.Explore = 3\n            Rate.Drop.Item.Poor = 3\n            Rate.Drop.Item.Normal = 3\n            Rate.Drop.Item.Uncommon = 3\n            Rate.Drop.Item.Rare = 2\n            Rate.Drop.Item.Epic = 1\n            Rate.Drop.Money = 3\n            Rate.Reputation.Gain = 3\n            MailDeliveryDelay = 0\n            SOAP.Enabled = 1\n            SOAP.IP = 0.0.0.0\n            SOAP.Port = 7878\n            PlayerBot.UpdateMs = 1000\n            PlayerBot.ShowInWhoList = 1\n            PartyBot.AutoEquip = 1\n            BattleBot.AutoJoin = 1\n            AHBot.Enable = 1\n      realmd-config:\n        data:\n          realmd.conf: |\n            [RealmdConf]\n            ConfVersion=2024091701\n            LoginDatabaseInfo = \"vmangos-database;3306;mangos;mangos;realmd\"\n            LogsDir = \"/opt/vmangos/storage/logs\"\n            PatchesDir = \"./patches\"\n            MaxPingTime = 30\n            RealmServerPort = 3724\n            BindIP = \"0.0.0.0\"\n            TrustedProxyServers = \"\"\n            PidFile = \"\"\n            LogLevel.Console = 2\n            LogLevel.File = 2\n            LogTime = 0\n            LogFile = \"Realmd.log\"\n            LogTimestamp = 0\n            LogFileLevel = 0\n            UseProcessors = 0\n            ProcessPriority = 1\n            WaitAtStartupError = 0\n            MinRealmListDelay = 1\n            RealmsStateUpdateDelay = 20\n            WrongPass.MaxCount = 0\n            WrongPass.BanTime = 600\n            WrongPass.BanType = 0\n            ReqEmailVerification = 0\n            ReqEmailSince = 0\n            GeoLocking = 0\n            StrictVersionCheck = 1\n            SendMail = 0\n            MailFrom = \"\"\n            MailCertChecks = 1\n            SendGridKey = \"\"\n            GeolockGUID = \"\"\n            MaxSessionDuration = 300\n    persistence:\n      database:\n        existingClaim: vmangos-database\n        advancedMounts:\n          database:\n            app:\n              - path: /var/lib/mysql\n      data:\n        existingClaim: vmangos-data\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/vmangos/storage/data\n                readOnly: true\n      mangosd-config:\n        type: configMap\n        name: vmangos-mangosd-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/vmangos/config/mangosd.conf\n                subPath: mangosd.conf\n      realmd-config:\n        type: configMap\n        name: vmangos-realmd-config\n        advancedMounts:\n          realmd:\n            app:\n              - path: /opt/vmangos/config/realmd.conf\n                subPath: realmd.conf\n      mangosd-logs:\n        type: emptyDir\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/vmangos/storage/logs\n      realmd-logs:\n        type: emptyDir\n        advancedMounts:\n          realmd:\n            app:\n              - path: /opt/vmangos/storage/logs\n      honor:\n        type: emptyDir\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/vmangos/storage/honor\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc-database.yaml\n  - pvc-data.yaml\n  - tcproutes.yaml\n  - dnsendpoint.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/pvc-data.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: vmangos-data\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/pvc-database.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: vmangos-database\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: vmangos-database\nspec:\n  sourcePVC: vmangos-database\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: vmangos-database-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/tcproutes.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: vmangos-auth\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: vmangos-auth\n  rules:\n    - backendRefs:\n        - name: vmangos-auth\n          port: 3724\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: vmangos-world\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: vmangos-world\n  rules:\n    - backendRefs:\n        - name: vmangos-world\n          port: 8085\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: vmangos-database-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: vmangos-database-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": ".archive/kubernetes/vmangos/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: vmangos\n  namespace: game-servers\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 10m\n  path: \"./apps/base/game-servers/vmangos/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: game-servers\n"
  },
  {
    "path": ".claude/agents/README.md",
    "content": "# Claude Agents for GitOps Operations\n\nThis directory contains specialized Claude agent definitions for Kubernetes and DevOps/Platform engineering tasks in this FluxCD GitOps repository.\n\n## Available Agents\n\n| Agent | File | Purpose |\n|-------|------|---------|\n| **Flux Troubleshooter** | [flux-troubleshooter.md](./flux-troubleshooter.md) | Diagnose and resolve FluxCD resource issues |\n| **GitOps Deployer** | [gitops-deployer.md](./gitops-deployer.md) | Deploy applications following repository patterns |\n| **Security Auditor** | [security-auditor.md](./security-auditor.md) | Security review of manifests and configurations |\n| **Dependency Mapper** | [dependency-mapper.md](./dependency-mapper.md) | Map and validate Flux dependency chains |\n| **Resource Optimizer** | [resource-optimizer.md](./resource-optimizer.md) | Optimize resource requests/limits and autoscaling |\n\n## How to Use These Agents\n\n### Method 1: Reference Agent in Prompts\n\nWhen working with Claude Code, reference an agent by name:\n\n```\n\"As the Flux Troubleshooter agent, diagnose why the prometheus\nHelmRelease in the observability namespace is failing to reconcile.\"\n```\n\n```\n\"As the GitOps Deployer agent, deploy Grafana Tempo to the\nobservability namespace using the official Grafana OCI Helm chart.\"\n```\n\n### Method 2: Use Agent Context\n\nClaude Code will automatically use agent context when the task matches the agent's expertise:\n\n```\n\"Why is my prometheus HelmRelease failing?\"\n→ Claude may automatically use Flux Troubleshooter agent context\n```\n\n```\n\"Add Redis to the database namespace\"\n→ Claude may automatically use GitOps Deployer agent context\n```\n\n### Method 3: Explicit Agent Mode\n\nSome Claude Code interfaces may support explicit agent selection:\n\n```\n/agent flux-troubleshooter\nDiagnose prometheus reconciliation failure\n```\n\n## Quick Start Examples\n\n### Deploy New Application\n\n```\nAs the GitOps Deployer agent:\n\nDeploy Grafana Mimir to the observability namespace.\n- Use official Grafana OCI Helm chart\n- Configure S3 backend (use existing thanos bucket)\n- Enable distributed mode with 3 replicas\n- Create SOPS-encrypted secret for S3 credentials\n```\n\n**Expected Output:**\n- Complete directory structure\n- All required YAML manifests\n- SOPS encryption commands\n- Deployment instructions\n\n### Troubleshoot Flux Issue\n\n```\nAs the Flux Troubleshooter agent:\n\nThe kube-prometheus-stack HelmRelease is stuck in \"Upgrade Failed\".\nDiagnose the root cause and provide remediation steps.\n```\n\n**Expected Output:**\n- Status analysis\n- Root cause identification\n- Step-by-step remediation\n- Verification commands\n\n### Security Audit\n\n```\nAs the Security Auditor agent:\n\nAudit all manifests in the network-system namespace for security issues.\nFocus on secret management, pod security standards, and RBAC.\n```\n\n**Expected Output:**\n- Structured security report\n- Severity-rated issues\n- Remediation steps for each issue\n- Compliance summary\n\n### Map Dependencies\n\n```\nAs the Dependency Mapper agent:\n\nMap the complete dependency chain for all applications in the\nistio-system and istio-ingress namespaces.\n```\n\n**Expected Output:**\n- Dependency tree visualization\n- Reconciliation order\n- Validation results\n- Optimization recommendations\n\n### Optimize Resources\n\n```\nAs the Resource Optimizer agent:\n\nAnalyze the observability namespace and recommend resource optimizations.\nProvide cost savings estimates and HPA configurations.\n```\n\n**Expected Output:**\n- Current vs actual usage analysis\n- Optimized resource recommendations\n- HPA configurations\n- Cost savings estimates\n\n## Common Workflows\n\n### 1. Complete Application Deployment\n\nChain multiple agents for end-to-end deployment:\n\n```\nStep 1 - Deploy:\n  As the GitOps Deployer agent, deploy <app> to <namespace>\n\nStep 2 - Secure:\n  As the Security Auditor agent, audit <namespace>/<app>\n\nStep 3 - Validate:\n  As the Dependency Mapper agent, verify <app> dependencies\n\nStep 4 - Monitor:\n  As the Flux Troubleshooter agent, verify <app> reconciliation\n```\n\n### 2. Incident Response\n\n```\nStep 1 - Diagnose:\n  As the Flux Troubleshooter agent, diagnose <issue>\n\nStep 2 - Dependencies:\n  As the Dependency Mapper agent, check if dependencies are healthy\n\nStep 3 - Optimize:\n  As the Resource Optimizer agent, check for resource exhaustion\n```\n\n### 3. Security Hardening\n\n```\nStep 1 - Audit:\n  As the Security Auditor agent, audit all namespaces\n\nStep 2 - Validate:\n  Review and apply security recommendations\n```\n\n## Agent Capabilities Summary\n\n### Flux Troubleshooter\n✅ Diagnose HelmRelease failures\n✅ Diagnose Kustomization failures\n✅ Check controller health\n✅ Trace dependency issues\n✅ Provide remediation steps\n\n### GitOps Deployer\n✅ Create application directory structure\n✅ Generate HelmRelease + OCIRepository\n✅ Configure Flux Kustomizations\n✅ Set up SOPS secrets\n✅ Create cluster overlays\n✅ Follow repository conventions\n\n### Security Auditor\n✅ Scan for unencrypted secrets\n✅ Validate pod security standards\n✅ Review RBAC configurations\n✅ Check network policies\n✅ Identify privilege escalation\n✅ Verify SOPS encryption\n\n### Dependency Mapper\n✅ Build dependency graphs\n✅ Detect circular dependencies\n✅ Calculate reconciliation order\n✅ Validate cross-namespace refs\n✅ Suggest optimizations\n✅ Identify critical path\n\n### Resource Optimizer\n✅ Analyze resource usage\n✅ Recommend requests/limits\n✅ Configure HPA\n✅ Calculate cost savings\n✅ Right-size workloads\n✅ Identify over/under-provisioning\n\n## Repository Context\n\nAll agents have access to repository-specific context:\n\n- **Cluster**: cluster-00 (default)\n- **Branch**: main (auto-reconciled by Flux)\n- **Bootstrap**: Flux Operator (not traditional `flux bootstrap`)\n- **Charts**: OCIRepository (not HelmRepository)\n- **Secrets**: SOPS with PGP + Age + GCP KMS\n- **SOPS PGP**: `0635B8D34037A9453003FB7B93CAA682FF4C9014`\n- **SOPS Age**: `age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t`\n\n## Agent Development\n\n### Creating New Agents\n\nTo create a new agent:\n\n1. **Create agent file**: `.claude/agents/my-agent.md`\n2. **Define expertise**: List capabilities and focus area\n3. **Document workflow**: Step-by-step process the agent follows\n4. **Provide examples**: Commands, YAML snippets, expected outputs\n5. **Include context**: Repository-specific patterns and conventions\n6. **Test**: Validate agent with real repository tasks\n\n### Agent Template\n\n```markdown\n# [Agent Name] Agent\n\nYou are a [domain] expert specializing in [specific focus].\n\n## Expertise\n\n- List capabilities\n- Specific skills\n- Tools and technologies\n\n## Workflow\n\nWhen [task description], follow this approach:\n\n1. **Step 1**: Description\n2. **Step 2**: Description\n3. **Step 3**: Description\n\n## Common Patterns\n\n[Provide patterns, examples, code snippets]\n\n## Repository-Specific Context\n\n[Repository conventions and specifics]\n\n## Output Format\n\n[Expected output structure]\n```\n\n## Best Practices\n\n1. **Be Specific**: Provide clear context (namespace, app name, requirements)\n2. **Iterate**: Review agent output, refine with follow-up questions\n3. **Validate**: Always validate agent-generated code before applying\n4. **Chain Agents**: Use multiple agents for complex workflows\n5. **Learn**: Study agent outputs to understand GitOps patterns\n6. **Customize**: Fork and modify agents for your specific needs\n\n## Limitations\n\nAgents are guidance tools, not autonomous actors:\n\n- ⚠️ **Always review** generated YAML manifests\n- ⚠️ **Test in staging** before production\n- ⚠️ **Validate** against cluster policies\n- ⚠️ **Understand** the recommendations before applying\n- ⚠️ **Monitor** after applying changes\n\n## Integration Points\n\n### With FluxCD\n- Agents understand Flux Operator patterns\n- Generate FluxCD-compatible manifests\n- Follow repository's Flux conventions\n\n### With SOPS\n- Agents use repository SOPS configuration\n- Generate properly encrypted secrets\n- Configure Flux decryption automatically\n\n### With Kustomize\n- Agents follow base/overlay pattern\n- Generate valid Kustomize patches\n- Respect repository structure\n\n### With Helm\n- Agents use OCIRepository (not HelmRepository)\n- Follow HelmRelease conventions\n- Apply repository-wide defaults\n\n## Support\n\n- **Repository Guide**: See [/CLAUDE.md](../../CLAUDE.md)\n- **Documentation**: See [/docs](../../docs/)\n- **Task Automation**: See [/.taskfiles](../../.taskfiles/)\n- **FluxCD Docs**: https://fluxcd.io\n\n## Contributing\n\nImprovements welcome:\n\n1. Enhance existing agent workflows\n2. Add new agents for common tasks\n3. Improve examples and documentation\n4. Share success stories and patterns\n\nSubmit PRs with agent updates or create issues for new agent ideas.\n"
  },
  {
    "path": ".claude/agents/dependency-mapper.md",
    "content": "# Dependency Mapper Agent\n\nYou are a FluxCD dependency analysis expert specializing in mapping and validating Kustomization dependency chains.\n\n## Expertise\n\n- Build dependency directed acyclic graphs (DAGs)\n- Detect circular dependencies\n- Validate dependency order and reconciliation sequences\n- Suggest optimal dependency chains\n- Identify missing or incorrect dependencies\n- Calculate reconciliation timing\n\n## Analysis Workflow\n\n### 1. Extract Dependencies\n\nGet all Kustomizations and their dependencies:\n\n```bash\n# List all Kustomizations with dependencies\nkubectl get kustomization -A -o jsonpath='{range .items[*]}{.metadata.name}{\"\\t\"}{.metadata.namespace}{\"\\t\"}{.spec.dependsOn[*].name}{\"\\n\"}{end}' | column -t\n\n# Get specific Kustomization dependencies\nkubectl get kustomization -n flux-system <name> -o yaml | yq '.spec.dependsOn'\n```\n\n### 2. Build Dependency Graph\n\nCreate a directed graph where:\n- **Nodes**: Kustomization resources\n- **Edges**: `dependsOn` relationships\n- **Direction**: A → B means \"B depends on A\"\n\n### 3. Validate Graph Properties\n\nCheck for:\n- **Circular dependencies**: Invalid, will prevent reconciliation\n- **Missing dependencies**: Referenced Kustomization doesn't exist\n- **Cross-namespace references**: Valid but ensure namespace in `dependsOn`\n- **Orphaned resources**: Kustomizations with no dependents or dependencies\n\n### 4. Calculate Reconciliation Order\n\nUse topological sort to determine:\n1. **Level 0**: No dependencies (can reconcile immediately)\n2. **Level 1**: Depends only on Level 0\n3. **Level N**: Depends on Level N-1 or lower\n\nResources at the same level can reconcile in parallel.\n\n## Common Dependency Patterns\n\n### Core Infrastructure Dependencies\n\n```\ncert-manager (network-system)\n└── Ingress Controllers\n    └── Applications with Ingress\n\nkube-prometheus-stack CRDs (observability)\n└── kube-prometheus-stack Operator\n    └── ServiceMonitor/PodMonitor resources\n\nIstio Base (istio-system)\n└── Istio Istiod\n    └── Istio Gateway\n        └── VirtualServices/DestinationRules\n```\n\n### Storage Dependencies\n\n```\nRook-Ceph Operator (rook-ceph)\n└── Rook-Ceph Cluster\n    └── StorageClass/CephBlockPool\n        └── Applications with PVCs\n```\n\n### Common Patterns by System\n\n**Network System:**\n- cert-manager (no deps)\n- external-dns (depends on cert-manager)\n- ingress-nginx (depends on cert-manager)\n- oauth2-proxy (depends on cert-manager, ingress-nginx)\n\n**Observability:**\n- prometheus-operator-crds (no deps)\n- kube-prometheus-stack (depends on CRDs)\n- grafana (depends on prometheus)\n- loki (no deps, independent)\n- thanos (depends on prometheus)\n\n**Security System:**\n- kyverno-crds (no deps)\n- kyverno (depends on CRDs)\n- gatekeeper (no deps)\n- falco (no deps)\n\n**Istio:**\n- istio-base (no deps)\n- istio-istiod (depends on istio-base)\n- istio-gateway (depends on istio-istiod)\n- kiali (depends on istio-istiod, prometheus)\n\n## Dependency Validation Rules\n\n### Valid Dependencies\n\n✅ **Namespace before resources:**\n```yaml\n# Good: namespace created first\ndependsOn:\n  - name: observability-namespace\n```\n\n✅ **CRDs before operators:**\n```yaml\n# Good: CRDs installed first\ndependsOn:\n  - name: prometheus-operator-crds\n```\n\n✅ **Operators before instances:**\n```yaml\n# Good: operator ready before creating instances\ndependsOn:\n  - name: kube-prometheus-stack\n```\n\n### Invalid Dependencies\n\n❌ **Circular dependency:**\n```yaml\n# App A depends on App B\n# App B depends on App A\n# Result: Neither can reconcile\n```\n\n❌ **Missing dependency:**\n```yaml\n# References non-existent Kustomization\ndependsOn:\n  - name: non-existent-kustomization\n```\n\n❌ **Wrong namespace:**\n```yaml\n# Missing namespace field for cross-namespace dep\ndependsOn:\n  - name: cert-manager  # Incorrect\n# Should be:\ndependsOn:\n  - name: cert-manager\n    namespace: flux-system\n```\n\n### Unnecessary Dependencies\n\n⚠️ **Over-specification:**\n```yaml\n# Grafana doesn't need to depend on Loki\n# They can reconcile independently\ndependsOn:\n  - name: loki  # Unnecessary\n```\n\n## Analysis Commands\n\n### View Dependency Status\n\n```bash\n# Check if dependencies are ready\nflux get kustomization -A\n\n# Watch reconciliation order\nflux get kustomization -A --watch\n\n# Check specific dependency\nkubectl get kustomization -n flux-system <name> -o yaml | yq '.status.conditions'\n```\n\n### Find Blocking Dependencies\n\n```bash\n# Find Kustomizations that are not ready\nkubectl get kustomization -A -o json | jq -r '.items[] | select(.status.conditions[] | select(.type==\"Ready\" and .status!=\"True\")) | .metadata.name'\n\n# Check what's waiting\nkubectl get kustomization -A -o json | jq -r '.items[] | select(.status.conditions[] | select(.reason==\"DependencyNotReady\")) | \"\\(.metadata.name) waiting on \\(.status.conditions[].message)\"'\n```\n\n## Output Format\n\nProvide dependency analysis in this format:\n\n```\nDEPENDENCY TREE: [namespace/system]\n================================\n\nLevel 0 (No dependencies - can reconcile immediately):\n  - cert-manager (network-system)\n  - prometheus-operator-crds (observability)\n  - istio-base (istio-system)\n\nLevel 1 (Depends on Level 0):\n  - kube-prometheus-stack (observability)\n    → depends on: prometheus-operator-crds\n  - istio-istiod (istio-system)\n    → depends on: istio-base\n  - external-dns (network-system)\n    → depends on: cert-manager\n\nLevel 2 (Depends on Level 1 or below):\n  - prometheus (observability)\n    → depends on: kube-prometheus-stack\n  - istio-gateway (istio-ingress)\n    → depends on: istio-istiod\n\nRECONCILIATION ORDER:\n1. [Parallel] cert-manager, prometheus-operator-crds, istio-base\n2. [Parallel] kube-prometheus-stack, istio-istiod, external-dns\n3. [Parallel] prometheus, istio-gateway\n\nVALIDATION RESULTS:\n✓ No circular dependencies detected\n✓ All referenced Kustomizations exist\n✓ Cross-namespace dependencies valid\n⚠ Warning: [specific warning]\n\nRECOMMENDATIONS:\n1. [Specific recommendation with justification]\n2. [Another recommendation]\n\nCRITICAL PATH:\nistio-base → istio-istiod → istio-gateway (longest chain: 3 levels)\n```\n\n## Optimization Recommendations\n\n### Reduce Unnecessary Dependencies\n\nIf two resources can reconcile independently, don't create a dependency:\n\n```yaml\n# Bad: Grafana and Loki are independent\ngrafana:\n  dependsOn:\n    - name: loki\n\n# Good: Let them reconcile in parallel\ngrafana:\n  dependsOn:\n    - name: kube-prometheus-stack  # Only if Grafana needs Prometheus datasource\n\nloki:\n  dependsOn: []  # No dependencies\n```\n\n### Parallelize Reconciliation\n\nGroup independent resources to reconcile simultaneously:\n\n```yaml\n# All these can start in parallel if they share dependencies\n- prometheus\n- grafana\n- loki\n- jaeger\n# All depend on cert-manager, can reconcile together after cert-manager is ready\n```\n\n### Critical Path Optimization\n\nIdentify the longest dependency chain (critical path) and optimize:\n\n1. Remove unnecessary dependencies in the chain\n2. Ensure critical path components have higher reconciliation frequency\n3. Consider pre-installing critical path components during bootstrap\n\n## Troubleshooting Dependency Issues\n\n### Kustomization Stuck on DependencyNotReady\n\n```bash\n# Check which dependency is not ready\nkubectl get kustomization -n flux-system <name> -o yaml | yq '.status.conditions[] | select(.reason==\"DependencyNotReady\")'\n\n# Check the dependency's status\nkubectl get kustomization -n flux-system <dependency-name> -o yaml | yq '.status.conditions'\n```\n\n### Circular Dependency Detection\n\nIf Kustomizations are never becoming ready:\n\n1. Map all `dependsOn` relationships\n2. Look for cycles: A → B → C → A\n3. Break the cycle by removing one dependency\n4. Force reconcile: `flux reconcile kustomization <name> -n flux-system`\n\n### Missing Dependency\n\n```bash\n# List all Kustomizations\nkubectl get kustomization -A\n\n# Check if referenced dependency exists\nkubectl get kustomization -n flux-system <dependency-name>\n```\n\n## Repository-Specific Context\n\nThis repository:\n- Uses **flux-system** namespace for all Kustomization resources\n- Follows pattern: `[system-name]-[app-name]` for Kustomization names\n- Common base dependencies: cert-manager, CRD kustomizations\n- Bootstrap order defined in `kubernetes/clusters/cluster-00/`\n\nAlways reference resources with `namespace/name` format for clarity.\n"
  },
  {
    "path": ".claude/agents/flux-troubleshooter.md",
    "content": "# Flux Troubleshooter Agent\n\nYou are a FluxCD troubleshooting expert specializing in diagnosing and resolving FluxCD resource issues.\n\n## Expertise\n\n- Analyze Flux resource status and conditions (HelmReleases, Kustomizations, OCIRepositories, GitRepositories)\n- Check controller health and logs\n- Trace dependency chains\n- Identify common reconciliation failures\n- Suggest remediation steps\n\n## Troubleshooting Workflow\n\nWhen analyzing Flux issues, follow this systematic approach:\n\n1. **Check Resource Status**\n   - Get resource with `kubectl get <resource-type> -n <namespace> <name> -o yaml`\n   - Examine `.status.conditions` for error messages\n   - Check `.status.lastAttemptedRevision` vs `.status.lastAppliedRevision`\n\n2. **Verify Dependencies**\n   - Review `spec.dependsOn` in Kustomizations\n   - Ensure all dependencies are healthy and ready\n   - Check if dependency chain is correct\n\n3. **Validate Source Resources**\n   - For HelmReleases: Check referenced OCIRepository or HelmRepository\n   - For Kustomizations: Check referenced GitRepository or OCIRepository\n   - Verify source is reconciling successfully\n\n4. **Check SOPS Decryption**\n   - If secrets involved, verify decryption config in Kustomization\n   - Ensure `sops-gpg` or `sops-age` secret exists in namespace\n   - Check for decryption errors in kustomize-controller logs\n\n5. **Review Controller Logs**\n   - `kubectl logs -n flux-system deploy/helm-controller --since=30m`\n   - `kubectl logs -n flux-system deploy/kustomize-controller --since=30m`\n   - `kubectl logs -n flux-system deploy/source-controller --since=30m`\n\n6. **Examine Managed Resources**\n   - Check `.status.inventory` for list of managed resources\n   - Verify each managed resource exists and is healthy\n   - Look for resource conflicts or stuck finalizers\n\n7. **Provide Root Cause Analysis**\n   - Identify the specific failure point\n   - Explain why it's failing\n   - Provide actionable remediation steps with exact commands\n\n## Common Issues & Solutions\n\n### HelmRelease Failures\n\n**CRD Version Mismatch:**\n- Update CRDs to required version\n- Force reconcile: `flux reconcile helmrelease -n <namespace> <name>`\n\n**Values Validation Error:**\n- Check values.yaml against chart schema\n- Verify variable substitution is working\n\n**Chart Not Found:**\n- Verify OCIRepository URL is correct\n- Check chart version exists: `helm show chart oci://<url>`\n\n### Kustomization Failures\n\n**Decryption Failed:**\n- Verify SOPS secret exists: `kubectl get secret -n flux-system sops-gpg`\n- Check encryption fingerprints match\n\n**Dependency Not Ready:**\n- Check dependency status\n- Ensure dependency order is correct\n\n**Source Not Found:**\n- Verify GitRepository is reconciling\n- Check branch/tag/commit exists\n\n## Repository-Specific Context\n\nThis repository uses:\n- **Flux Operator** (not traditional `flux bootstrap`)\n- **OCIRepository** for Helm charts (not HelmRepository)\n- **SOPS** encryption with PGP + Age + GCP KMS\n- **Cluster**: cluster-00 (default)\n- **Branch**: main (auto-reconciled)\n\n## Output Format\n\nAlways provide:\n1. **Status Summary**: Current state of the resource\n2. **Root Cause**: Specific reason for failure\n3. **Remediation Steps**: Exact commands to fix the issue\n4. **Verification**: How to confirm the fix worked\n\nUse code references with `file:line` format when referencing manifests.\n"
  },
  {
    "path": ".claude/agents/gitops-deployer.md",
    "content": "# GitOps Application Deployer Agent\n\nYou are a GitOps application deployment expert specializing in FluxCD-based deployments following this repository's patterns.\n\n## Expertise\n\n- Generate complete application structures following repository conventions\n- Create HelmRelease + OCIRepository manifests\n- Set up SOPS-encrypted secrets\n- Configure Kustomizations with proper dependencies\n- Create overlays for cluster-specific customization\n- Apply repository naming and labeling conventions\n\n## Deployment Workflow\n\nWhen deploying a new application:\n\n1. **Create Directory Structure**\n   ```\n   kubernetes/apps/base/[system-name]/[app-name]/\n   ├── app/\n   │   ├── helmrelease.yaml\n   │   ├── kustomization.yaml\n   │   ├── ocirepository.yaml\n   │   ├── values.yaml\n   │   └── secret.enc.yaml (if needed)\n   ├── ks.yaml\n   └── namespace.yaml (if new namespace)\n   ```\n\n2. **System Categories**\n   - `kube-system`: Core Kubernetes components\n   - `network-system`: Networking (cert-manager, external-dns, ingress)\n   - `observability`: Monitoring stack (Prometheus, Grafana, Loki, Thanos)\n   - `security-system`: Security (Kyverno, Falco, Gatekeeper)\n   - `istio-system` & `istio-ingress`: Service mesh\n   - `home-system`: Home automation & media apps\n   - `rook-ceph`: Storage cluster\n   - `database`: Database workloads\n\n3. **Create OCIRepository**\n   ```yaml\n   apiVersion: source.toolkit.fluxcd.io/v1beta2\n   kind: OCIRepository\n   metadata:\n     name: [app-name]-chart\n     namespace: [namespace]\n   spec:\n     url: oci://[registry]/[chart-name]\n     interval: 1h\n     ref:\n       semver: \">=X.Y.Z\"  # or tag: \"X.Y.Z\"\n   ```\n\n4. **Create HelmRelease**\n   ```yaml\n   apiVersion: helm.toolkit.fluxcd.io/v2\n   kind: HelmRelease\n   metadata:\n     name: [app-name]\n   spec:\n     chartRef:\n       kind: OCIRepository\n       name: [app-name]-chart\n       namespace: [namespace]\n     interval: 30m\n     timeout: 10m\n     valuesFrom:\n       - kind: ConfigMap\n         name: [app-name]-values\n         optional: true\n       - kind: Secret\n         name: [app-name]-secrets\n         optional: true\n     values:\n       # Minimal required values\n   ```\n\n5. **Create Flux Kustomization (ks.yaml)**\n   ```yaml\n   apiVersion: kustomize.toolkit.fluxcd.io/v1\n   kind: Kustomization\n   metadata:\n     name: [system-name]-[app-name]\n     namespace: flux-system\n     labels:\n       substitution.flux/enabled: \"true\"\n   spec:\n     interval: 10m\n     path: ./kubernetes/apps/base/[system-name]/[app-name]\n     prune: true\n     sourceRef:\n       kind: GitRepository\n       name: flux-system\n     dependsOn:\n       - name: [dependency-name]\n         namespace: flux-system\n     decryption:  # If secrets exist\n       provider: sops\n       secretRef:\n         name: sops-age\n     postBuild:\n       substituteFrom:\n         - kind: ConfigMap\n           name: cluster-config\n           optional: false\n         - kind: Secret\n           name: cluster-secrets\n           optional: false\n   ```\n\n6. **Create Namespace (if new)**\n   ```yaml\n   apiVersion: v1\n   kind: Namespace\n   metadata:\n     name: [namespace]\n     labels:\n       pod-security.kubernetes.io/enforce: privileged  # or restricted/baseline\n       pod-security.kubernetes.io/audit: privileged\n       pod-security.kubernetes.io/warn: privileged\n       goldilocks.fairwinds.com/enabled: \"true\"\n   ```\n\n7. **Create Secret (if needed)**\n   - Create unencrypted secret first\n   - Encrypt with SOPS: `sops -e secret.yaml > secret.enc.yaml`\n   - Delete unencrypted version\n   - Add `.enc.yaml` suffix\n\n8. **Update Parent Kustomization**\n   Add to `kubernetes/apps/base/[system-name]/kustomization.yaml`:\n   ```yaml\n   resources:\n     - [app-name]/ks.yaml\n   ```\n\n## Repository Conventions\n\n### File Naming\n- `ks.yaml`: Flux Kustomization resources (how to apply)\n- `kustomization.yaml`: Kustomize configuration (what to apply)\n- `*.enc.yaml`: SOPS-encrypted files\n- `helmrelease.yaml`: Helm release definitions\n- `ocirepository.yaml`: OCI chart sources\n- `namespace.yaml`: Namespace with pod security labels\n\n### HelmRelease Global Defaults\nAll HelmReleases automatically inherit these defaults:\n```yaml\ninstall:\n  crds: CreateReplace\n  createNamespace: true\n  replace: true\n  strategy: RetryOnFailure\n  timeout: 10m\nrollback:\n  recreate: true\n  force: true\n  cleanupOnFail: true\nupgrade:\n  cleanupOnFail: true\n  crds: CreateReplace\n  remediation:\n    remediateLastFailure: true\n    retries: 3\n    strategy: rollback\n```\n\n### Common Dependencies\n- CRDs → Operators → Applications\n- Namespaces → RBAC → Applications\n- cert-manager → Ingress controllers → Apps\n- Storage → Databases → Applications\n\n## OCI Registry Locations\n\nCommon OCI registries:\n- **Prometheus Community**: `oci://ghcr.io/prometheus-community/charts/[chart]`\n- **Grafana**: `oci://ghcr.io/grafana/charts/[chart]`\n- **Bitnami**: `oci://registry-1.docker.io/bitnamicharts/[chart]`\n- **GitLab**: `oci://registry.gitlab.com/[project]/charts/[chart]`\n- **CNCF**: Check ArtifactHub for OCI support\n\n## Output Format\n\nProvide:\n1. **Complete directory structure** with all files\n2. **All YAML manifests** properly formatted\n3. **Instructions** for encryption and application\n4. **Verification steps** to confirm deployment\n5. **File references** using `file:line` format\n\nAfter generating manifests, recommend:\n- Security audit with Security Auditor agent\n- Validation with Manifest Validator agent\n- Dependency check with Dependency Mapper agent\n"
  },
  {
    "path": ".claude/agents/resource-optimizer.md",
    "content": "# Resource Optimizer Agent\n\nYou are a Kubernetes resource optimization expert specializing in right-sizing resource requests/limits and configuring autoscaling.\n\n## Expertise\n\n- Analyze actual resource usage from metrics\n- Recommend optimal resource requests and limits\n- Configure Horizontal Pod Autoscaler (HPA)\n- Configure Vertical Pod Autoscaler (VPA) recommendations\n- Identify over-provisioned and under-provisioned workloads\n- Calculate cost savings and efficiency improvements\n- Balance performance, cost, and reliability\n\n## Optimization Workflow\n\n### 1. Gather Current State\n\n```bash\n# Current resource usage\nkubectl top pods -n <namespace>\nkubectl top nodes\n\n# Current resource requests/limits\nkubectl get pods -n <namespace> -o jsonpath='{range .items[*]}{.metadata.name}{\"\\t\"}{.spec.containers[*].resources}{\"\\n\"}{end}'\n\n# HPA status\nkubectl get hpa -n <namespace>\n\n# VPA recommendations (if deployed)\nkubectl get vpa -n <namespace> -o yaml\n```\n\n### 2. Analyze Historical Metrics\n\nUse Prometheus queries to get historical data:\n\n```promql\n# CPU usage over 30 days (P50, P90, P99)\nquantile_over_time(0.50, container_cpu_usage_seconds_total{namespace=\"<namespace>\"}[30d])\nquantile_over_time(0.90, container_cpu_usage_seconds_total{namespace=\"<namespace>\"}[30d])\nquantile_over_time(0.99, container_cpu_usage_seconds_total{namespace=\"<namespace>\"}[30d])\n\n# Memory usage over 30 days\nquantile_over_time(0.90, container_memory_working_set_bytes{namespace=\"<namespace>\"}[30d])\n\n# Request vs actual usage\nsum(rate(container_cpu_usage_seconds_total{namespace=\"<namespace>\"}[5m])) by (pod)\n/ on(pod)\nsum(kube_pod_container_resource_requests{resource=\"cpu\", namespace=\"<namespace>\"}) by (pod)\n```\n\n### 3. Calculate Recommendations\n\n#### CPU Requests\n- **Base on P90 usage** with 20-30% headroom for bursts\n- Align to node capacity for efficient bin-packing\n- Consider workload type:\n  - **Latency-sensitive**: Higher headroom (30-40%)\n  - **Batch jobs**: Lower headroom (10-20%)\n  - **Bursty workloads**: Lower requests, rely on limits\n\n#### CPU Limits\n- **Option 1**: 2-4x requests (allows bursting)\n- **Option 2**: No limit (avoid CPU throttling, use QoS Burstable)\n- **Never set limits** below actual P95 usage\n\n#### Memory Requests\n- **Base on P90 usage** with 20-30% headroom\n- Memory is incompressible - ensure adequate requests\n- Account for heap growth (Java, Node.js)\n\n#### Memory Limits\n- **Set 1.5-2x requests** to handle spikes\n- **Avoid limits for JVM apps** (can cause OOM instead of graceful GC)\n- **Set limits** for memory leak protection\n\n### 4. QoS Classes\n\nChoose appropriate Quality of Service class:\n\n**Guaranteed** (requests == limits):\n- Critical workloads\n- Predictable resource usage\n- Last to be evicted\n```yaml\nresources:\n  requests:\n    cpu: 500m\n    memory: 1Gi\n  limits:\n    cpu: 500m\n    memory: 1Gi\n```\n\n**Burstable** (requests < limits or only requests):\n- Most applications (recommended)\n- Can use extra resources when available\n```yaml\nresources:\n  requests:\n    cpu: 500m\n    memory: 1Gi\n  limits:\n    cpu: 2000m\n    memory: 2Gi\n```\n\n**BestEffort** (no requests/limits):\n- Non-critical batch jobs\n- First to be evicted\n- Not recommended for production\n\n## Horizontal Pod Autoscaler (HPA)\n\n### CPU-Based HPA\n\n```yaml\napiVersion: autoscaling/v2\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: example-hpa\n  namespace: example-namespace\nspec:\n  scaleTargetRef:\n    apiVersion: apps/v1\n    kind: Deployment\n    name: example-app\n  minReplicas: 2\n  maxReplicas: 10\n  metrics:\n    - type: Resource\n      resource:\n        name: cpu\n        target:\n          type: Utilization\n          averageUtilization: 70  # Target 70% CPU utilization\n  behavior:\n    scaleDown:\n      stabilizationWindowSeconds: 300  # Wait 5min before scaling down\n      policies:\n        - type: Percent\n          value: 50  # Scale down max 50% of pods at once\n          periodSeconds: 60\n    scaleUp:\n      stabilizationWindowSeconds: 0  # Scale up immediately\n      policies:\n        - type: Percent\n          value: 100  # Scale up max 100% (double) at once\n          periodSeconds: 15\n```\n\n### Memory-Based HPA\n\n```yaml\nmetrics:\n  - type: Resource\n    resource:\n      name: memory\n      target:\n        type: Utilization\n        averageUtilization: 80\n```\n\n### Custom Metrics HPA\n\n```yaml\nmetrics:\n  - type: Pods\n    pods:\n      metric:\n        name: http_requests_per_second\n      target:\n        type: AverageValue\n        averageValue: \"1000\"\n```\n\n### HPA Configuration Guidelines\n\n**Min Replicas:**\n- At least 2 for high availability\n- Consider failure domains (zones)\n\n**Max Replicas:**\n- Based on peak traffic capacity\n- Consider backend capacity (database connections)\n- Cost constraints\n\n**Target Utilization:**\n- **CPU**: 70-80% (allows headroom for bursts)\n- **Memory**: 80-85% (less bursty than CPU)\n\n**Behavior:**\n- **Scale up quickly** (seconds to minutes)\n- **Scale down slowly** (minutes to hours) to avoid flapping\n\n## Resource Optimization Patterns\n\n### Over-Provisioned (Wasteful)\n\n**Symptoms:**\n- Actual usage << requests (e.g., 10% utilization)\n- Many idle resources\n- High cost-to-usage ratio\n\n**Action:**\n- Reduce requests to P90 + 20%\n- Consider reducing replicas\n- Add HPA for elasticity\n\n### Under-Provisioned (Risky)\n\n**Symptoms:**\n- Actual usage ≥ requests/limits\n- Frequent OOM kills\n- CPU throttling\n- Performance degradation\n\n**Action:**\n- Increase requests/limits immediately\n- Add HPA to handle demand spikes\n- Investigate memory leaks if memory keeps growing\n\n### Right-Sized (Optimal)\n\n**Target:**\n- Actual usage: 60-80% of requests\n- 20-40% headroom for bursts\n- No CPU throttling\n- No OOM kills\n- Cost-effective\n\n## Cost Optimization Strategies\n\n### 1. Reduce Over-Provisioning\n- Lower requests for under-utilized pods\n- Use smaller instance types\n- **Estimated savings**: 20-50% of compute costs\n\n### 2. Implement HPA\n- Scale to zero (or min replicas) during low traffic\n- Auto-scale during peak hours\n- **Estimated savings**: 30-70% for variable workloads\n\n### 3. Use Spot/Preemptible Nodes\n- For fault-tolerant workloads\n- Combine with node affinity\n- **Estimated savings**: 60-80% vs on-demand\n\n### 4. Bin-Packing Efficiency\n- Align resource requests to node capacity\n- Use pod topology spread constraints\n- **Estimated savings**: 10-30% through better utilization\n\n## Repository Integration\n\n### Update HelmRelease Values\n\nAdd to `values.yaml`:\n\n```yaml\nresources:\n  requests:\n    cpu: 500m\n    memory: 1Gi\n  limits:\n    cpu: 2000m\n    memory: 2Gi\n\nautoscaling:\n  enabled: true\n  minReplicas: 2\n  maxReplicas: 10\n  targetCPUUtilizationPercentage: 75\n  targetMemoryUtilizationPercentage: 80\n```\n\n### Create Cluster Overlay\n\nFor cluster-specific resource tuning:\n\n```yaml\n# kubernetes/apps/overlays/cluster-00/observability/prometheus/resources-patch.yaml\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: prometheus\nspec:\n  values:\n    server:\n      resources:\n        requests:\n          cpu: 1000m\n          memory: 4Gi\n        limits:\n          cpu: 4000m\n          memory: 8Gi\n```\n\n## Output Format\n\nProvide optimization report:\n\n```\nRESOURCE OPTIMIZATION REPORT: [namespace]\n==========================================\n\nWORKLOAD: [name]\n----------------\n\nCurrent Configuration:\n  Replicas: 3\n  Requests: {cpu: 1000m, memory: 2Gi}\n  Limits: {cpu: 2000m, memory: 4Gi}\n  HPA: Not configured\n\nActual Usage (30-day P90):\n  CPU: 450m (45% of requests)\n  Memory: 1.2Gi (60% of requests)\n\nUtilization Analysis:\n  ⚠ Over-provisioned CPU by 55%\n  ✓ Memory usage appropriate\n\nRecommendations:\n  Requests: {cpu: 500m, memory: 1.5Gi}  # Reduce CPU by 50%, memory by 25%\n  Limits: {cpu: 1500m, memory: 3Gi}\n\n  Add HPA:\n    minReplicas: 2\n    maxReplicas: 5\n    targetCPUUtilization: 75%\n\nExpected Impact:\n  - Cost savings: $XX/month (XX% reduction)\n  - Improved bin-packing: +2 pods per node\n  - Risk: LOW (maintains 20% headroom)\n\nYAML Configuration:\n---\n[Provide complete YAML]\n\n```\n\n## Monitoring & Validation\n\nAfter optimization:\n\n```bash\n# Monitor resource usage\nkubectl top pods -n <namespace> --watch\n\n# Check for OOM kills\nkubectl get events -n <namespace> | grep OOM\n\n# Check for CPU throttling\nkubectl get pods -n <namespace> -o json | jq '.items[] | select(.status.containerStatuses[].state.waiting.reason == \"CrashLoopBackOff\")'\n\n# Monitor HPA\nkubectl get hpa -n <namespace> --watch\n\n# Check pod evictions\nkubectl get events -n <namespace> | grep Evicted\n```\n\n## Best Practices\n\n1. **Start conservative**: Better to over-provision initially\n2. **Iterate**: Adjust based on actual usage over weeks\n3. **Test**: Validate in staging before production\n4. **Monitor**: Set alerts for high resource usage\n5. **Document**: Note assumptions and expected patterns\n6. **Review**: Quarterly resource optimization reviews\n\nAlways provide before/after YAML, expected impact, and validation steps.\n"
  },
  {
    "path": ".claude/agents/security-auditor.md",
    "content": "# Security Auditor Agent\n\nYou are a Kubernetes security expert specializing in auditing GitOps configurations for security best practices.\n\n## Expertise\n\n- Scan for unencrypted secrets\n- Validate pod security standards\n- Review RBAC configurations\n- Identify privilege escalation risks\n- Verify network policies\n- Review SOPS encryption patterns\n- Check for CVE-prone configurations\n\n## Audit Workflow\n\nWhen reviewing configurations, systematically check:\n\n### 1. Secret Management\n\n**Critical Checks:**\n- All secrets MUST use `.enc.yaml` suffix (SOPS encrypted)\n- No base64-encoded secrets without SOPS encryption\n- Verify SOPS fingerprints match repository config:\n  - PGP: `0635B8D34037A9453003FB7B93CAA682FF4C9014`\n  - Age: `age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t`\n\n**Commands:**\n```bash\n# Find unencrypted secrets\ngrep -r \"kind: Secret\" kubernetes/apps/ | grep -v \".enc.yaml\"\n\n# Verify SOPS encryption\nsops -d path/to/secret.enc.yaml\n```\n\n### 2. Pod Security Standards\n\n**Critical Checks:**\n- Namespaces MUST have `pod-security.kubernetes.io/enforce` label\n- No `privileged: true` unless absolutely required\n- No `hostNetwork: true`, `hostPID: true`, `hostIPC: true`\n- No `runAsUser: 0` (root) unless required\n- `allowPrivilegeEscalation: false` should be set\n- Capabilities should be dropped: `drop: [ALL]`\n- Read-only root filesystem when possible\n\n**Acceptable Security Contexts:**\n```yaml\nsecurityContext:\n  allowPrivilegeEscalation: false\n  runAsNonRoot: true\n  runAsUser: 1000\n  runAsGroup: 1000\n  fsGroup: 1000\n  seccompProfile:\n    type: RuntimeDefault\n  capabilities:\n    drop: [ALL]\n  readOnlyRootFilesystem: true\n```\n\n**Commands:**\n```bash\n# Check namespace labels\ngrep -r \"pod-security.kubernetes.io\" kubernetes/apps/\n\n# Find privileged pods\ngrep -r \"privileged: true\" kubernetes/apps/\n\n# Find host namespace usage\ngrep -rE \"host(Network|PID|IPC): true\" kubernetes/apps/\n```\n\n### 3. RBAC Configuration\n\n**Critical Checks:**\n- Principle of least privilege applied\n- No wildcard (`*`) permissions on resources or verbs\n- ServiceAccounts properly scoped\n- No `cluster-admin` binding unless required\n- Token auto-mounting disabled when not needed: `automountServiceAccountToken: false`\n\n**Risky Permissions:**\n- `create` on `pods/exec` (remote code execution)\n- `*` on `secrets` (credential access)\n- `*` on `*` (full cluster access)\n- `escalate` or `bind` on roles (privilege escalation)\n\n**Commands:**\n```bash\n# Find wildcard permissions\ngrep -rE \"- \\\"\\*\\\"\" kubernetes/apps/\n\n# Check ServiceAccount usage\ngrep -r \"serviceAccountName:\" kubernetes/apps/\n```\n\n### 4. Network Security\n\n**Critical Checks:**\n- NetworkPolicies exist for namespaces with sensitive workloads\n- Default deny policies where appropriate\n- Ingress/egress restrictions defined\n- Service mesh policies (Istio AuthorizationPolicy) configured\n\n**Recommended NetworkPolicy:**\n```yaml\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  name: default-deny-ingress\nspec:\n  podSelector: {}\n  policyTypes:\n    - Ingress\n```\n\n### 5. Supply Chain Security\n\n**Critical Checks:**\n- Images should use digest pinning: `image@sha256:...`\n- Images from trusted registries only\n- Chart sources verified (OCIRepository with semver)\n- Renovate automation configured for updates\n\n**Trusted Registries:**\n- `ghcr.io` (GitHub Container Registry)\n- `gcr.io`, `registry.k8s.io` (Google/Kubernetes)\n- `quay.io` (Red Hat Quay)\n- Internal registry if configured\n\n**Commands:**\n```bash\n# Find tag-based images (not digest)\ngrep -rE \"image:.*:[^@]*$\" kubernetes/apps/\n```\n\n### 6. Resource Limits\n\n**Critical Checks:**\n- Resource requests and limits defined\n- No unbounded resource consumption\n- QoS class appropriate (Guaranteed for critical workloads)\n\n**Recommended:**\n```yaml\nresources:\n  requests:\n    cpu: 100m\n    memory: 128Mi\n  limits:\n    cpu: 500m\n    memory: 512Mi\n```\n\n### 7. Admission Control\n\n**Critical Checks:**\n- Kyverno or OPA policies applied\n- Pod Security Admission enabled\n- Image verification policies active\n- Mutation webhooks for security defaults\n\n## Severity Ratings\n\nUse these severity levels:\n\n- **CRITICAL**: Immediate security risk (unencrypted secrets, privileged containers)\n- **HIGH**: Significant risk (missing RBAC, no network policies, root user)\n- **MEDIUM**: Moderate risk (no resource limits, tag-based images)\n- **LOW**: Best practice violation (missing labels, verbose logging)\n- **INFO**: Recommendations for improvement\n\n## Output Format\n\nProvide structured audit report:\n\n```\nSECURITY AUDIT REPORT: [namespace/app]\n=========================================\n\nCRITICAL:\n[CRIT-1] Issue title\n- File: path/to/file.yaml:line\n- Issue: Detailed description\n- Risk: Impact explanation\n- Fix: Exact remediation steps\n\nHIGH:\n[HIGH-1] Issue title\n...\n\nMEDIUM:\n...\n\nLOW:\n...\n\nPASSED:\n✓ Check description\n✓ Check description\n\nSUMMARY:\n- Total issues: X\n- Critical: X, High: X, Medium: X, Low: X\n- Files scanned: X\n- Compliance: X%\n```\n\n## Repository-Specific Context\n\n- **SOPS Keys**: PGP `0635B8D...`, Age `age19gj...`\n- **Pod Security**: Most namespaces use `privileged` enforcement\n- **Service Mesh**: Istio deployed, use AuthorizationPolicy\n- **Policy Engines**: Kyverno and OPA Gatekeeper available\n- **Runtime Security**: Falco and Tetragon for detection\n\n## Remediation Priority\n\n1. **Immediate** (Critical): Unencrypted secrets, privileged containers\n2. **Within 24h** (High): Missing RBAC, root users, host namespaces\n3. **Within week** (Medium): Resource limits, network policies\n4. **Next sprint** (Low): Image digests, labels, documentation\n\nAlways reference files with `file:line` format for easy navigation.\n"
  },
  {
    "path": ".gitattributes",
    "content": ".secrets/git-crypt/** filter=git-crypt diff=git-crypt\n*.enc.yaml diff=sopsdiffer\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners\n* @xUnholy\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\nWe follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).\n\nPlease contact info@owncloud.ai to report an issue.\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing Guide\n\n[Instructions](https://contribute.cncf.io/maintainers/github/templates/required/contributing/#introduction)\n\n- [Contributing Guide](#contributing-guide)\n  - [Ways to Contribute](#ways-to-contribute)\n  - [Find an Issue](#find-an-issue)\n  - [Ask for Help](#ask-for-help)\n  - [Sign Your Commits](#sign-your-commits)\n    - [DCO](#dco)\n  - [Pull Request Checklist](#pull-request-checklist)\n\nWelcome! We are glad that you want to contribute to our project! 💖\n\nAs you get started, you are in the best position to give us feedback on areas of\nour project that we need help with including:\n\n* Gaps in our Guide or documentation\n* Bugs in our automation scripts\n\nIf anything doesn't make sense, or doesn't work when you run it, please open a\nbug report and let us know!\n\n## Ways to Contribute\n\nWe welcome many different types of contributions including:\n\n* New features\n* Builds, CI/CD\n* Bug fixes\n* Documentation\n* Issue Triage\n* Answering questions on Discord\n* Web design\n* Communications / Social Media / Blog Posts\n* Release management\n\nNot everything happens through a GitHub pull request. Please contact us and let's discuss how we can work together - Email: info@owncloud.ai\n\n## Find an Issue\n\nWe have good first issues for new contributors and help wanted issues suitable\nfor any contributor. [good first issue]([TODO](https://github.com/xUnholy/k8s-gitops/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)) has extra information to\nhelp you make your first contribution. [help wanted]([TODO](https://github.com/xUnholy/k8s-gitops/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)) are issues\nsuitable for someone who isn't a core maintainer and is good to move onto after\nyour first pull request.\n\nSometimes there won’t be any issues with these labels. That’s ok! There is\nlikely still something for you to work on. If you want to contribute but you\ndon’t know where to start or can't find a suitable issue, you can ask for an issue to work on.\n\nOnce you see an issue that you'd like to work on, please post a comment saying\nthat you want to work on it. Something like \"I want to work on this\" is fine.\n\n## Ask for Help\n\nThe best way to reach us with a question when contributing is to ask on:\n\n* The original github issue\n* Our Discord channel\n\n## Sign Your Commits\n\n[Instructions](https://contribute.cncf.io/maintainers/github/templates/required/contributing/#sign-your-commits)\n\n### DCO\nLicensing is important to open source projects. It provides some assurances that\nthe software will continue to be available based under the terms that the\nauthor(s) desired. We require that contributors sign off on commits submitted to\nour project's repositories. The [Developer Certificate of Origin\n(DCO)](https://probot.github.io/apps/dco/) is a way to certify that you wrote and\nhave the right to contribute the code you are submitting to the project.\n\nYou sign-off by adding the following to your commit messages. Your sign-off must\nmatch the git user and email associated with the commit.\n\n    This is my commit message\n\n    Signed-off-by: Your Name <your.name@example.com>\n\nGit has a `-s` command line option to do this automatically:\n\n    git commit -s -m 'This is my commit message'\n\nIf you forgot to do this and have not yet pushed your changes to the remote\nrepository, you can amend your commit with the sign-off by running\n\n    git commit --amend -s\n\n## Pull Request Checklist\n\nWhen you submit your pull request, or you push new commits to it, our automated\nsystems will run some checks on your new code. We require that your pull request\npasses these checks, but we also have more criteria than just that before we can\naccept and merge it.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yaml",
    "content": "---\nname: Bug Report\ndescription: Report a problem with the cluster or an application\nlabels: [\"bug\"]\nbody:\n  - type: dropdown\n    id: system\n    attributes:\n      label: System\n      description: Which system is affected?\n      options:\n        - kube-system\n        - network-system\n        - observability\n        - security-system\n        - home-system\n        - game-servers\n        - ai-system\n        - rook-ceph\n        - flux-system\n        - other\n    validations:\n      required: true\n  - type: input\n    id: application\n    attributes:\n      label: Application\n      description: Which application is affected?\n      placeholder: e.g. cert-manager, home-assistant\n    validations:\n      required: true\n  - type: textarea\n    id: description\n    attributes:\n      label: Description\n      description: What happened?\n    validations:\n      required: true\n  - type: textarea\n    id: expected\n    attributes:\n      label: Expected Behavior\n      description: What should have happened?\n    validations:\n      required: true\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant Logs\n      description: Paste relevant logs or Flux events\n      render: shell\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yaml",
    "content": "---\nname: Feature Request\ndescription: Propose a new application or cluster enhancement\nlabels: [\"enhancement\"]\nbody:\n  - type: textarea\n    id: description\n    attributes:\n      label: Description\n      description: What would you like to add or change?\n    validations:\n      required: true\n  - type: textarea\n    id: rationale\n    attributes:\n      label: Rationale\n      description: Why is this needed?\n    validations:\n      required: true\n  - type: textarea\n    id: implementation\n    attributes:\n      label: Implementation Notes\n      description: Any thoughts on how to implement this?\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "## Summary\n\n<!-- Brief description of what this PR does and why -->\n\n## Changes\n\n-\n\n## Test Plan\n\n- [ ] `pre-commit run --all-files` passes\n- [ ] Flux Local diff reviewed in PR comments\n- [ ] Secrets are encrypted (`.enc.yaml` / `.enc.age.yaml`)\n\n## Checklist\n\n- [ ] YAML is valid and passes yamllint\n- [ ] No unencrypted secrets committed\n- [ ] Dependencies updated in `ks.yaml` if needed\n- [ ] Relevant documentation updated\n"
  },
  {
    "path": ".github/renovate.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  extends: [\n    \"config:recommended\",\n    // TODO: Consider using best-practices once OCI sha256 digests are supported\n    // \"config:best-practices\",\n    \"docker:enableMajor\",\n    \"security:openssf-scorecard\",\n    \":automergeBranch\",\n    \":automergeDigest\",\n    \":disableRateLimiting\",\n    \":dependencyDashboard\",\n    \":semanticCommits\",\n    \":timezone(Australia/Melbourne)\",\n    \"github>xunholy/k8s-gitops//.renovate/autoMerge.json5\",\n    \"github>xunholy/k8s-gitops//.renovate/changelogs.json5\",\n    \"github>xunholy/k8s-gitops//.renovate/customManagers.json5\",\n    \"github>xunholy/k8s-gitops//.renovate/grafanaDashboards.json5\",\n    \"github>xunholy/k8s-gitops//.renovate/groups.json5\",\n    \"github>xunholy/k8s-gitops//.renovate/labels.json5\",\n    \"github>xunholy/k8s-gitops//.renovate/semanticCommits.json5\",\n  ],\n  dependencyDashboardTitle: \"Renovate Dashboard 🤖\",\n  suppressNotifications: [\"prEditedNotification\", \"prIgnoreNotification\"],\n  \"pre-commit\": {\n    enabled: true,\n  },\n  ignorePaths: [\"**/*.enc.*\", \"**/resources/**\"],\n  flux: {\n    managerFilePatterns: [\"/(^|/)kubernetes/.+\\\\.ya?ml$/\"],\n  },\n  \"helm-values\": {\n    managerFilePatterns: [\"/(^|/)kubernetes/.+\\\\.ya?ml$/\"],\n  },\n  kubernetes: {\n    managerFilePatterns: [\"/(^|/)kubernetes/.+\\\\.ya?ml$/\"],\n  },\n}\n"
  },
  {
    "path": ".github/workflows/azerothcore.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Build AzerothCore WotLK\"\n\non:\n  workflow_dispatch: {}\n  push:\n    branches:\n      - main\n    paths:\n      - .github/workflows/azerothcore.yaml\n      - kubernetes/apps/base/game-servers/azerothcore/app/resources/**\n\npermissions: write-all\n\nenv:\n  CONTEXT: kubernetes/apps/base/game-servers/azerothcore/app/resources\n  WORLDSERVER_IMAGE: ghcr.io/xunholy/azerothcore-wotlk-worldserver\n  AUTHSERVER_IMAGE: ghcr.io/xunholy/azerothcore-wotlk-authserver\n  DB_IMPORT_IMAGE: ghcr.io/xunholy/azerothcore-wotlk-db-import\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Login to GHCR\n        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4\n\n      - name: Build and push worldserver\n        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7\n        with:\n          context: ${{ env.CONTEXT }}\n          target: worldserver\n          push: true\n          tags: |\n            ${{ env.WORLDSERVER_IMAGE }}:${{ github.sha }}\n            ${{ env.WORLDSERVER_IMAGE }}:latest\n          build-args: THREADS=2\n          cache-from: type=gha,scope=azerothcore\n          cache-to: type=gha,mode=max,scope=azerothcore\n\n      - name: Build and push authserver\n        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7\n        with:\n          context: ${{ env.CONTEXT }}\n          target: authserver\n          push: true\n          tags: |\n            ${{ env.AUTHSERVER_IMAGE }}:${{ github.sha }}\n            ${{ env.AUTHSERVER_IMAGE }}:latest\n          build-args: THREADS=2\n          cache-from: type=gha,scope=azerothcore\n          cache-to: type=gha,mode=max,scope=azerothcore\n\n      - name: Build and push db-import\n        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7\n        with:\n          context: ${{ env.CONTEXT }}\n          target: db-import\n          push: true\n          tags: |\n            ${{ env.DB_IMPORT_IMAGE }}:${{ github.sha }}\n            ${{ env.DB_IMPORT_IMAGE }}:latest\n          build-args: THREADS=2\n          cache-from: type=gha,scope=azerothcore\n          cache-to: type=gha,mode=max,scope=azerothcore\n"
  },
  {
    "path": ".github/workflows/cmangos-registration.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Build CMaNGOS Registration\"\n\non:\n  workflow_dispatch: {}\n  push:\n    branches:\n      - main\n    paths:\n      - .github/workflows/cmangos-registration.yaml\n      - kubernetes/apps/base/game-servers/cmangos-registration/app/resources/**\n\npermissions: write-all\n\nenv:\n  IMAGE: ghcr.io/xunholy/cmangos-registration\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Login to GHCR\n        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4\n\n      - name: Build and push\n        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7\n        with:\n          context: kubernetes/apps/base/game-servers/cmangos-registration/app/resources\n          push: true\n          tags: |\n            ${{ env.IMAGE }}:${{ github.sha }}\n            ${{ env.IMAGE }}:latest\n          cache-from: type=gha\n          cache-to: type=gha,mode=max\n"
  },
  {
    "path": ".github/workflows/cmangos.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Build CMaNGOS Classic\"\n\non:\n  workflow_dispatch: {}\n  push:\n    branches:\n      - main\n    paths:\n      - .github/workflows/cmangos.yaml\n      - kubernetes/apps/base/game-servers/cmangos/app/resources/**\n\npermissions: write-all\n\nenv:\n  BUILDER_IMAGE: ghcr.io/xunholy/cmangos-classic-builder\n  RUNNER_IMAGE: ghcr.io/xunholy/cmangos-classic\n\njobs:\n  build-builder:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Login to GHCR\n        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4\n\n      - name: Build and push builder\n        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7\n        with:\n          context: kubernetes/apps/base/game-servers/cmangos/app/resources\n          target: builder\n          push: true\n          tags: |\n            ${{ env.BUILDER_IMAGE }}:${{ github.sha }}\n            ${{ env.BUILDER_IMAGE }}:latest\n          build-args: |\n            THREADS=4\n            COMMIT_SHA=${{ github.sha }}\n          cache-from: |\n            type=gha,scope=builder\n            type=registry,ref=${{ env.BUILDER_IMAGE }}:latest\n          cache-to: type=gha,mode=max,scope=builder\n\n  build-runner:\n    runs-on: ubuntu-latest\n    needs: build-builder\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Login to GHCR\n        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4\n\n      - name: Build and push runner\n        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7\n        with:\n          context: kubernetes/apps/base/game-servers/cmangos/app/resources\n          target: runner\n          push: true\n          tags: |\n            ${{ env.RUNNER_IMAGE }}:${{ github.sha }}\n            ${{ env.RUNNER_IMAGE }}:latest\n          build-args: |\n            THREADS=4\n            COMMIT_SHA=${{ github.sha }}\n          cache-from: |\n            type=gha,scope=builder\n            type=gha,scope=runner\n            type=registry,ref=${{ env.RUNNER_IMAGE }}:latest\n          cache-to: type=gha,mode=max,scope=runner\n"
  },
  {
    "path": ".github/workflows/dex-k8s-authenticator.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Build dex-k8s-authenticator\"\n\non:\n  workflow_dispatch: {}\n  push:\n    branches:\n      - main\n    paths:\n      - .github/workflows/dex-k8s-authenticator.yaml\n      - kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/**\n\npermissions: write-all\n\nenv:\n  IMAGE: ghcr.io/xunholy/dex-k8s-authenticator\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Login to GHCR\n        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4\n\n      - name: Build and push\n        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7\n        with:\n          context: kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources\n          push: true\n          tags: |\n            ${{ env.IMAGE }}:${{ github.sha }}\n            ${{ env.IMAGE }}:latest\n          cache-from: type=gha\n          cache-to: type=gha,mode=max\n"
  },
  {
    "path": ".github/workflows/flux-local.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: Flux Local\n\non:\n  pull_request:\n    branches:\n      - main\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.number || github.ref }}\n  cancel-in-progress: true\n\npermissions:\n  contents: read\n\njobs:\n  filter:\n    name: Flux Local - Filter\n    runs-on: ubuntu-latest\n    outputs:\n      changed-files: ${{ steps.changed-files.outputs.changed_files }}\n    steps:\n      - name: Get Changed Files\n        id: changed-files\n        uses: bjw-s-labs/action-changed-files@a9a36fb08ce06db9b02fbd8026cc2c0945eb9841 # v0.6.0\n        with:\n          patterns: kubernetes/**/*\n  test:\n    if: ${{ needs.filter.outputs.changed-files != '[]' }}\n    needs: filter\n    name: Flux Local - Test\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        cluster: [\"cluster-00\"]\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n\n      - name: Run flux-local test\n        uses: docker://ghcr.io/allenporter/flux-local:v8.2.0@sha256:9c77739d8d7c71b808311693ea52d603d1ddb5190d3d4f23e47f6f33d5254602\n        with:\n          args: >-\n            test\n            --all-namespaces\n            --enable-helm\n            --path /github/workspace/kubernetes/clusters/${{ matrix.cluster }}\n            --sources \"flux-system=kubernetes/\"\n            --verbose\n            --skip-invalid-kustomization-paths\n\n  diff:\n    if: ${{ needs.filter.outputs.changed-files != '[]' }}\n    needs: filter\n    name: Flux Local - Diff\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: write\n    strategy:\n      matrix:\n        cluster: [\"cluster-00\"]\n        resource: [\"helmrelease\", \"kustomization\"]\n      fail-fast: false\n    steps:\n      - name: Checkout Pull Request Branch\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          path: pull\n\n      - name: Checkout Default Branch\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          ref: ${{ github.event.repository.default_branch }}\n          path: default\n\n      - name: Run flux-local diff\n        uses: docker://ghcr.io/allenporter/flux-local:v8.2.0@sha256:9c77739d8d7c71b808311693ea52d603d1ddb5190d3d4f23e47f6f33d5254602\n        with:\n          args: >-\n            diff ${{ matrix.resource }}\n            --unified 6\n            --path /github/workspace/pull/kubernetes/clusters/${{ matrix.cluster }}\n            --path-orig /github/workspace/default/kubernetes/clusters/${{ matrix.cluster }}\n            --strip-attrs \"helm.sh/chart,checksum/config,app.kubernetes.io/version,chart\"\n            --limit-bytes 10000\n            --all-namespaces\n            --sources \"flux-system=kubernetes/\"\n            --output-file diff.patch\n            --skip-invalid-kustomization-paths\n\n      - name: Generate Diff\n        id: diff\n        run: |-\n          echo 'diff<<EOF' >> $GITHUB_OUTPUT\n          [ -f diff.patch ] && cat diff.patch >> $GITHUB_OUTPUT\n          echo 'EOF' >> $GITHUB_OUTPUT\n\n      - if: ${{ steps.diff.outputs.diff != '' }}\n        name: Generate Token\n        uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0\n        id: app-token\n        with:\n          app-id: ${{ secrets.BOT_APP_ID }}\n          private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }}\n\n      - if: ${{ steps.diff.outputs.diff != '' }}\n        name: Add Comment\n        continue-on-error: true\n        uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4\n        with:\n          GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}\n          header: ${{ github.event.pull_request.number }}/kubernetes/${{ matrix.resource }}\n          message: |-\n            ```diff\n            ${{ steps.diff.outputs.diff }}\n            ```\n\n  success:\n    if: ${{ !cancelled() }}\n    needs: [\"test\", \"diff\"]\n    name: Flux Local - Success\n    runs-on: ubuntu-latest\n    steps:\n      - name: Any jobs failed?\n        if: ${{ contains(needs.*.result, 'failure') }}\n        run: exit 1\n\n      - name: All jobs passed or skipped?\n        if: ${{ !(contains(needs.*.result, 'failure')) }}\n        run: echo \"All jobs passed or skipped\" && echo \"${{ toJSON(needs.*.result) }}\"\n"
  },
  {
    "path": ".github/workflows/oci.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Publish OCI artifact\"\n\non:\n  workflow_dispatch: {}\n  push:\n    branches:\n      - main\n    paths:\n      - .github/workflows/oci.yaml\n      - kubernetes/**\n\n# Default GITHUB_TOKEN token permissions do NOT support cosign and must be enabled.\n# This is to set the package and id_token permissions to read|write.\n# Current default permissions can be viewed here: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token\npermissions: write-all\n\nenv:\n  OCI_REPO: \"oci://ghcr.io/xunholy/manifests/${{ github.event.repository.name }}\"\n  GHCR_REPO: \"ghcr.io/xunholy/manifests/${{ github.event.repository.name }}\"\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    env:\n      COSIGN_EXPERIMENTAL: \"true\"\n      COSIGN_YES: \"true\"\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Setup Flux CLI\n        uses: fluxcd/flux2/action@main\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Setup Crane\n        uses: imjasonh/setup-crane@6da1ae018866400525525ce74ff892880c099987 # v0.5\n\n      - name: Setup Cosign\n        uses: sigstore/cosign-installer@main\n\n      - name: Login to GHCR\n        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Create OCI artifact\n        run: |\n          flux push artifact \"$OCI_REPO:$(git rev-parse --short HEAD)\" \\\n            --path=\"./kubernetes\" \\\n            --source=\"$(git config --get remote.origin.url)\" \\\n            --revision=\"$(git branch --show-current)@sha1:$(git rev-parse HEAD)\" \\\n            --ignore-paths=\"sops-gpg.encrypted.yaml,sops-age.encrypted.yaml,.sops.pub.asc\" \\\n            --reproducible\n\n      - name: Create OCI artifact tag\n        run: |\n          flux tag artifact \"$OCI_REPO:$(git rev-parse --short HEAD)\" --tag main\n\n      - name: Get the digest of the OCI artifact\n        id: crane\n        run: |\n          DIGEST=$(crane digest \"$GHCR_REPO:$(git rev-parse --short HEAD)\")\n          echo \"DIGEST=$DIGEST\" >> $GITHUB_OUTPUT\n\n      - name: Sign the OCI artifact\n        run: cosign sign \"$GHCR_REPO@${{ steps.crane.outputs.DIGEST }}\" -y\n"
  },
  {
    "path": ".github/workflows/oidc.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Example: GCP Workload identity Federation\"\n\non:\n  workflow_dispatch: {}\n\njobs:\n  connect:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: 'write' # Required for requesting the JWT\n      contents: 'read'  # Required for actions/checkout\n\n    steps:\n    # actions/checkout MUST come before auth\n    - uses: 'actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd' # v6 # Checkout your repository\n\n    # Authenticate to Google Cloud using the workload identity federation\n    - id: 'auth'\n      name: 'Authenticate to Google Cloud'\n      uses: 'google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093' # v3\n      with:\n        create_credentials_file: 'true' # Create a credentials file\n        # Set the workload identity provider and service account\n        workload_identity_provider: 'projects/970557914270/locations/global/workloadIdentityPools/raspbernetes-oidc-pool/providers/github-provider'\n        service_account: 'raspbernetes-oidc-sa@raspbernetes.iam.gserviceaccount.com'\n\n    - name: 'Set up Cloud SDK'\n      uses: 'google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db' # v3\n\n    - id: 'gcloud'\n      name: 'gcloud'\n      run: |-\n        gcloud auth login --brief --cred-file=\"${{ steps.auth.outputs.credentials_file_path }}\"\n        gcloud services list\n"
  },
  {
    "path": ".github/workflows/render-talos-manifests.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Render Talos Integration Manifests\"\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - kubernetes/apps/base/kube-system/kubelet-csr-approver/app/values.yaml\n      - kubernetes/apps/base/kube-system/kubelet-csr-approver/app/ocirepository.yaml\n  workflow_dispatch: {}\n\npermissions:\n  contents: write\n\njobs:\n  render:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Setup Helm\n        uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5\n\n      - name: Extract chart version from OCIRepository\n        id: chart\n        run: |\n          VERSION=$(grep -A2 'ref:' kubernetes/apps/base/kube-system/kubelet-csr-approver/app/ocirepository.yaml | grep 'tag:' | awk '{print $2}')\n          echo \"version=$VERSION\" >> \"$GITHUB_OUTPUT\"\n          echo \"Chart version: $VERSION\"\n\n      - name: Pull chart\n        env:\n          CHART_VERSION: ${{ steps.chart.outputs.version }}\n        run: |\n          helm pull oci://ghcr.io/postfinance/charts/kubelet-csr-approver \\\n            --version \"$CHART_VERSION\" \\\n            --untar \\\n            --destination /tmp/chart\n\n      - name: Render manifest\n        run: |\n          helm template kubelet-csr-approver /tmp/chart/kubelet-csr-approver \\\n            --namespace kube-system \\\n            --values kubernetes/apps/base/kube-system/kubelet-csr-approver/app/values.yaml \\\n            --no-hooks \\\n            > /tmp/rendered.yaml\n\n      - name: Setup yq\n        uses: mikefarah/yq@751d8ad57b84f1794661bc70c0afb92a22ad7b3c # v4.53.2\n\n      - name: Build final manifest with header and annotations\n        env:\n          CHART_VERSION: ${{ steps.chart.outputs.version }}\n        run: |\n          {\n          cat <<EOF\n          # This manifest was generated by automation. DO NOT EDIT.\n          # Chart: kubelet-csr-approver v${CHART_VERSION}\n          # Source: oci://ghcr.io/postfinance/charts/kubelet-csr-approver\n          # Values: kubernetes/apps/base/kube-system/kubelet-csr-approver/app/values.yaml\n          EOF\n          yq 'select(. != null) | .metadata.annotations += {\"meta.helm.sh/release-name\": \"kubelet-csr-approver\", \"meta.helm.sh/release-namespace\": \"kube-system\"}' /tmp/rendered.yaml\n          } > talos/integrations/cert-approver/cert-approver.yaml\n\n      - name: Update kustomization version\n        env:\n          CHART_VERSION: ${{ steps.chart.outputs.version }}\n        run: |\n          sed -i \"s/version: .*/version: $CHART_VERSION/\" \\\n            talos/integrations/cert-approver/kustomization.yaml\n\n      - name: Check for changes\n        id: diff\n        run: |\n          git diff --quiet talos/integrations/cert-approver/ && echo \"changed=false\" >> \"$GITHUB_OUTPUT\" || echo \"changed=true\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Commit and push\n        if: steps.diff.outputs.changed == 'true'\n        env:\n          CHART_VERSION: ${{ steps.chart.outputs.version }}\n        run: |\n          git config user.name \"github-actions[bot]\"\n          git config user.email \"41898282+github-actions[bot]@users.noreply.github.com\"\n          git add talos/integrations/cert-approver/\n          git commit -m \"chore(talos): re-render kubelet-csr-approver manifest v${CHART_VERSION}\"\n          git push\n"
  },
  {
    "path": ".github/workflows/renovate.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Renovate\"\n\non:\n  merge_group:\n  workflow_dispatch:\n    inputs:\n      dryRun:\n        description: Dry Run\n        default: false\n        type: boolean\n        required: true\n      logLevel:\n        description: Log Level\n        default: info\n        type: choice\n        options:\n          - debug\n          - info\n          - warn\n          - error\n          - fatal\n        required: false\n      version:\n        description: Renovate Version\n        default: latest\n        required: false\n  schedule:\n    - cron: \"0 * * * *\"\n  push:\n    branches:\n      - main\n    paths:\n      - .github/workflows/renovate.yaml\n      - .github/renovate.json5\n      - .github/renovate/**.json5\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  renovate:\n    name: Renovate\n    runs-on: ubuntu-latest\n    steps:\n      - name: Generate Token\n        uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3\n        id: app-token\n        with:\n          app-id: \"${{ secrets.BOT_APP_ID }}\"\n          private-key: \"${{ secrets.BOT_APP_PRIVATE_KEY }}\"\n\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          persist-credentials: false\n          token: \"${{ steps.app-token.outputs.token }}\"\n\n\n      - name: Renovate\n        uses: renovatebot/github-action@693b9ef15eec82123529a37c782242f091365961 # v46.1.14\n        env:\n          LOG_LEVEL: \"${{ inputs.logLevel || 'debug' }}\"\n          RENOVATE_DRY_RUN: \"${{ inputs.dryRun }}\"\n          RENOVATE_PLATFORM: github\n          RENOVATE_PLATFORM_COMMIT: true\n          RENOVATE_AUTODISCOVER: true\n          RENOVATE_AUTODISCOVER_FILTER: \"${{ github.repository }}\"\n          RENOVATE_INTERNAL_CHECKS_FILTER: strict\n        with:\n          configurationFile: .github/renovate.json5\n          token: \"x-access-token:${{ steps.app-token.outputs.token }}\"\n          renovate-version: \"${{ inputs.version || 'latest' }}\"\n"
  },
  {
    "path": ".github/workflows/terraform.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Terraform: Plan And Apply\"\n\non:\n  workflow_dispatch: {}\n  pull_request:\n    branches:\n      - main\n    paths:\n      - '.github/workflows/terraform.yaml'\n      - 'terraform/**'\n\nenv:\n  tf_actions_working_dir: terraform/gcp\n  terraform_version: 1.9.8\n\njobs:\n  plan:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: ${{ env.tf_actions_working_dir }}\n    steps:\n      - name: checkout\n        id: checkout_code\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - uses: 'google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093' # v3\n        with:\n          credentials_json: ${{ secrets.GCP_SA_KEY }}\n\n      - uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1\n        with:\n          project_id: ${{ secrets.GCP_PROJECT_ID }}\n          export_default_credentials: true\n\n      - uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4\n        with:\n          terraform_version: ${{ env.terraform_version }}\n\n      - name: Terraform fmt\n        id: fmt\n        run: terraform fmt -check\n        continue-on-error: false\n\n      - name: Terraform Lint\n        uses: reviewdog/action-tflint@master\n        with:\n          github_token: ${{ secrets.github_token }}\n          reporter: github-pr-review\n          fail_on_error: 'true'\n          filter_mode: 'nofilter'\n\n      - name: Terraform Init\n        id: init\n        run: terraform init\n        continue-on-error: false\n\n      - name: Terraform Validate\n        id: validate\n        run: terraform validate -no-color\n        continue-on-error: false\n\n      - name: Terraform Plan\n        id: plan\n        run: terraform plan -no-color\n        continue-on-error: false\n\n      - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0\n        if: github.event_name == 'pull_request'\n        env:\n          PLAN: \"terraform\\n${{ steps.plan.outputs.stdout }}\"\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          script: |\n            const output = `#### Terraform Format and Style 🖌 \\`${{ steps.fmt.outcome }}\\`\n            #### Terraform Initialization ⚙️ \\`${{ steps.init.outcome }}\\`\n            #### Terraform Validation 🤖 ${{ steps.validate.outputs.stdout }}\n            #### Terraform Plan 📖 \\`${{ steps.plan.outcome }}\\`\n\n            <details><summary>Show Plan</summary>\n\n            \\`\\`\\`${process.env.PLAN}\\`\\`\\`\n\n            </details>\n\n            *Pusher: @${{ github.actor }}, Action: \\`${{ github.event_name }}\\`, Working Directory: \\`${{ env.tf_actions_working_dir }}\\`, Workflow: \\`${{ github.workflow }}\\`*`;\n\n            github.issues.createComment({\n              issue_number: context.issue.number,\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              body: output\n            }\n\n  apply:\n    runs-on: ubuntu-latest\n    if: github.event_name != 'pull_request'\n    needs: [\"plan\"]\n    defaults:\n      run:\n        working-directory: ${{ env.tf_actions_working_dir }}\n    steps:\n      - name: checkout\n        id: checkout_code\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - uses: 'google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093' # v3\n        with:\n          credentials_json: ${{ secrets.GCP_SA_KEY }}\n\n      - uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1\n        with:\n          project_id: ${{ secrets.GCP_PROJECT_ID }}\n          export_default_credentials: true\n\n      - uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4\n        with:\n          terraform_version: ${{ env.terraform_version }}\n\n      - name: Terraform Init\n        id: init\n        run: terraform init\n        continue-on-error: false\n\n      - name: Terraform Apply\n        id: apply\n        run: terraform apply -no-color -auto-approve -input=false\n        continue-on-error: false\n"
  },
  {
    "path": ".github/workflows/test-e2e.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\nname: \"Flux: Run E2E Tests In KIND\"\n\non:\n  workflow_dispatch: {}\n\nenv:\n  DEFAULT_BRANCH: main\n\n# TODO: Fine-grained scope\n# permissions:\n#   contents: write      # (REQUIRED): [read] Used for actions/checkout - [write] Used for FluxCD bootstrap\n#   pull-requests: write # (REQUIRED): [write] Used for FluxCD bootstrap\n#   id-token: 'write'    # (REQUIRED): Used for requesting the JWT\n\npermissions: write-all\n\njobs:\n  kubernetes:\n    runs-on: ubuntu-latest\n    steps:\n      # Checkout the repository\n      - name: Checkout\n        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\n\n      - name: Setup Homebrew\n        uses: Homebrew/actions/setup-homebrew@master\n\n      - name: Setup Tools\n        run: |\n          brew install fluxcd/tap/flux go-task/tap/go-task sops kubernetes-cli\n\n      - name: Setup Kubernetes Kind\n        uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0\n        with:\n          version: \"v0.18.0\"\n\n      - name: 'Set up Cloud SDK'\n        uses: 'google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db' # v3\n\n      - id: 'auth'\n        name: 'Authenticate to Google Cloud'\n        uses: 'google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093' # v3\n        with:\n          create_credentials_file: 'true' # Create a credentials file\n          # Set the workload identity provider and service account\n          workload_identity_provider: 'projects/970557914270/locations/global/workloadIdentityPools/raspbernetes-oidc-pool/providers/github-provider'\n          service_account: 'raspbernetes-oidc-sa@raspbernetes.iam.gserviceaccount.com'\n\n      - name: Run task flux\n        env:\n          CLUSTER: e2e\n          GITHUB_USER: ${{ github.repository_owner }}\n          GITHUB_REPO: ${{ github.event.repository.name }}\n          GITHUB_BRANCH: ${{ github.head_ref || env.DEFAULT_BRANCH }}\n          GITHUB_TOKEN: ${{ secrets.FLUX_FINE_GRAINED_E2E_PAT }}\n        run: |\n          task core:gpg CLUSTER=\"$CLUSTER\"\n          task flux CLUSTER=\"$CLUSTER\" GITHUB_USER=\"$GITHUB_USER\" GITHUB_REPO=\"$GITHUB_REPO\" GITHUB_BRANCH=\"$GITHUB_BRANCH\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# Ignore the following repositories and files\n.DS_Store\n\n# Local .terraform directories\n**/.terraform/*\n\n# .tfstate files\n*.tfstate\n*.tfstate.*\n\n# Crash log files\ncrash.log\ncrash.*.log\n\n# Exclude all .tfvars files, which are likely to contain sensitive data, such as\n# password, private keys, and other secrets. These should not be part of version\n# control as they are data points which are potentially sensitive and subject\n# to change depending on the environment.\n*.tfvars\n*.tfvars.json\n\n# Ignore override files as they are usually used to override resources locally and so\n# are not checked in\noverride.tf\noverride.tf.json\n*_override.tf\n*_override.tf.json\n\n# Ignore CLI configuration files\n.terraformrc\nterraform.rc\n\n# Ignore tf lock files\n**/.terraform.lock.hcl\n\n# Ignore VSCODE SOPS decrypted files\n**/.decrypted~*\n\n# If you prefer the allow list template instead of the deny list, see community template:\n# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore\n#\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\n\n# Go workspace file\ngo.work\n\n# Ignore the hacks directory containing the scripts to run locally\nhacks/**\n\n# Ignore crossplane packages that have been built locally\n*.xpkg\n\n# Ignore Kubernetes configs\nkubeconfig\n\n# Ignore Talos configs\ntalosconfig\n\n# Ignore sensitive files\n*.agekey\n*.pub\n*.key\n*.pem\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "# See https://pre-commit.com for more information\n# See https://pre-commit.com/hooks.html for more hooks\nrepos:\n  - repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v6.0.0\n    hooks:\n      - id: trailing-whitespace\n      - id: end-of-file-fixer\n      - id: check-added-large-files\n      - id: check-merge-conflict\n      - id: detect-private-key\n      - id: check-yaml\n        args: [--allow-multiple-documents]\n        exclude: ^kubernetes/apps/base/home-system/recyclarr/app/resources/recyclarr\\.yml$\n      - id: check-json\n      - id: check-toml\n      # Only enable this if we want to prevent commits directly to the main branch\n      # - id: no-commit-to-branch\n      #   args: [--branch, main]\n\n  - repo: https://github.com/adrienverge/yamllint.git\n    rev: v1.38.0\n    hooks:\n      - id: yamllint\n        args: [-c=.yamllint.yaml]\n\n  # TODO: Enable this once we have a markdownlint config\n  # - repo: https://github.com/igorshubovych/markdownlint-cli\n  #   rev: v0.44.0\n  #   hooks:\n  #     - id: markdownlint\n  #       args: [--fix]\n\n  - repo: https://github.com/koalaman/shellcheck-precommit\n    rev: v0.11.0\n    hooks:\n      - id: shellcheck\n        args: [--severity=warning]\n"
  },
  {
    "path": ".renovate/autoMerge.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  packageRules: [\n    {\n      description: \"Auto-merge GitHub Actions\",\n      matchManagers: [\"github-actions\"],\n      automerge: true,\n      automergeType: \"branch\",\n      matchUpdateTypes: [\"minor\", \"patch\", \"digest\"],\n      ignoreTests: true,\n    },\n    {\n      description: \"Auto-merge Helm / Docker minor + patch\",\n      matchDatasources: [\"helm\", \"docker\"],\n      automerge: true,\n      automergeType: \"pr\",\n      matchUpdateTypes: [\"minor\", \"patch\"],\n      ignoreTests: true,\n    },\n    {\n      description: \"Disable auto-merge for stateful home-system + game-servers apps (manual review required)\",\n      matchFileNames: [\n        \"kubernetes/apps/base/home-system/**\",\n        \"kubernetes/apps/base/game-servers/**\",\n      ],\n      automerge: false,\n    },\n    {\n      description: \"Auto-merge everything under .archive (unmaintained, lifecycle-only)\",\n      matchFileNames: [\".archive/**\"],\n      automerge: true,\n      automergeType: \"branch\",\n      ignoreTests: true,\n    },\n  ],\n}\n"
  },
  {
    "path": ".renovate/changelogs.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  packageRules: [\n    {\n      description: \"Changelog URL for 1Password Connect\",\n      matchPackageNames: [\"/1password/\"],\n      changelogUrl: \"https://github.com/1Password/connect/blob/main/CHANGELOG.md\",\n    },\n    {\n      description: \"Changelog URL for Cloudflared\",\n      matchPackageNames: [\"cloudflared\"],\n      changelogUrl: \"https://github.com/cloudflare/cloudflared/blob/master/RELEASE_NOTES\",\n    },\n    {\n      description: \"Changelog URL for Spegel\",\n      matchPackageNames: [\"/spegel/\"],\n      changelogUrl: \"https://github.com/spegel-org/spegel/blob/main/CHANGELOG.md\",\n    },\n  ],\n}\n"
  },
  {
    "path": ".renovate/customManagers.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  customManagers: [\n    {\n      customType: \"regex\",\n      description: \"Process annotated dependencies\",\n      managerFilePatterns: [\n        \"/(^|/).+\\\\.env$/\",\n        \"/(^|/).+\\\\.sh$/\",\n        \"/(^|/).+\\\\.ya?ml(?:\\\\.j2)?$/\",\n      ],\n      matchStrings: [\n        // # renovate: datasource=github-releases depName=k3s-io/k3s\n        // k3s_release_version: &version v1.29.0+k3s1\n        // # renovate: datasource=helm depName=cilium repository=https://helm.cilium.io\n        // version: 1.15.1\n        // # renovate: datasource=docker depName=ghcr.io/siderolabs/kubelet\n        // KUBERNETES_VERSION=v1.31.1\n        \"datasource=(?<datasource>\\\\S+) depName=(?<depName>\\\\S+)( repository=(?<registryUrl>\\\\S+))?\\\\n.+(:\\\\s|=)(&\\\\S+\\\\s)?(?<currentValue>\\\\S+)\",\n        // # renovate: datasource=docker depName=ghcr.io/prometheus-operator/prometheus-operator\n        // https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.80.0/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml\n        \"datasource=(?<datasource>\\\\S+) depName=(?<depName>\\\\S+)\\\\n.+/(?<currentValue>(v|\\\\d)[^/]+)\",\n      ],\n      datasourceTemplate: \"{{#if datasource}}{{{datasource}}}{{else}}github-releases{{/if}}\",\n    },\n    {\n      customType: \"regex\",\n      description: \"Process OCI dependencies\",\n      managerFilePatterns: [\"/\\\\.yaml(?:\\\\.j2)?$/\"],\n      matchStrings: [\"oci://(?<depName>[^:]+):(?<currentValue>\\\\S+)\"],\n      datasourceTemplate: \"docker\",\n    },\n  ],\n}\n"
  },
  {
    "path": ".renovate/grafanaDashboards.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  customDatasources: {\n    \"grafana-dashboards\": {\n      defaultRegistryUrlTemplate: \"https://grafana.com/api/dashboards/{{packageName}}\",\n      format: \"json\",\n      transformTemplates: ['{\"releases\":[{\"version\": $string(revision)}], \"sourceDirectory\": name}'],\n    },\n  },\n  customManagers: [\n    {\n      description: \"Process Grafana dashboards\",\n      customType: \"regex\",\n      managerFilePatterns: [\"/grafanadashboard\\\\.yaml(?:\\\\.j2)?$/\",],\n      matchStrings: [\n        \"dashboards\\\\/(?<depName>\\\\d+)\\\\/revisions\\\\/(?<currentValue>\\\\d+)\\\\/download\",\n      ],\n      datasourceTemplate: \"custom.grafana-dashboards\",\n      versioningTemplate: \"regex:^(?<major>\\\\d+)$\",\n      autoReplaceStringTemplate: \"dashboards/{{depName}}/revisions/{{newValue}}/download\",\n    },\n  ],\n  packageRules: [\n    {\n      addLabels: [\"renovate/grafana-dashboard\"],\n      automerge: true,\n      automergeType: \"branch\",\n      commitMessageExtra: \"({{currentVersion}} ➔ {{newVersion}})\",\n      commitMessageTopic: \"dashboard {{sourceDirectory}}\",\n      ignoreTests: true,\n      matchDatasources: [\"custom.grafana-dashboards\"],\n      matchUpdateTypes: [\"major\"],\n      semanticCommitScope: \"grafana-dashboards\",\n      semanticCommitType: \"chore\",\n    },\n  ],\n}\n"
  },
  {
    "path": ".renovate/groups.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  packageRules: [\n    {\n      description: \"Actions Runner Controller Group\",\n      groupName: \"Actions Runner Controller\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\n        \"/gha-runner-scale-set-controller/\",\n        \"/gha-runner-scale-set/\",\n      ],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 2,\n    },\n    {\n      description: \"Talos Group\",\n      groupName: \"talos\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\"/installer/\"],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 2,\n    },\n    {\n      description: \"Cilium Group\",\n      groupName: \"Cilium\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\"/cilium/\"],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n    },\n    {\n      description: \"Flux Operator Group\",\n      groupName: \"Flux Operator\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\n        \"/flux-operator/\",\n        \"/flux-instance/\",\n        \"/flux-operator-manifests/\",\n      ],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 3,\n    },\n    {\n      description: \"Cert-Manager Group\",\n      groupName: \"Cert-Manager\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\"/cert-manager/\"],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n    },\n    {\n      description: \"kagent Group\",\n      groupName: \"kagent\",\n      matchDatasources: [\"docker\", \"helm\"],\n      matchPackagePatterns: [\"kagent\", \"kagent-crds\"],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 2,\n    },\n    {\n      description: \"kgateway Group\",\n      groupName: \"kgateway\",\n      matchDatasources: [\"helm\"],\n      matchPackagePatterns: [\"kgateway\", \"kgateway-crds\"],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 2,\n    },\n    {\n      description: \"Rook-Ceph Group\",\n      groupName: \"rook-ceph\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\"/rook-ceph/\", \"/rook-ceph-cluster/\"],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 2,\n    },\n    {\n      description: \"Kubernetes Group\",\n      groupName: \"kubernetes\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\n        \"/kube-apiserver/\",\n        \"/kube-controller-manager/\",\n        \"/kube-proxy/\",\n        \"/kube-scheduler/\",\n        \"/kubelet/\",\n      ],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 5,\n    },\n    {\n      description: \"Open WebUI Group\",\n      groupName: \"Open WebUI\",\n      matchDatasources: [\"helm\"],\n      matchPackageNames: [\"open-webui\"],\n      separateMajorMinor: false,\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n    },\n    {\n      description: \"1Password Connect Group\",\n      groupName: \"1password-connect\",\n      matchDatasources: [\"docker\"],\n      matchPackageNames: [\"/1password/\"],\n      group: {\n        commitMessageTopic: \"{{{groupName}}} group\",\n      },\n      minimumGroupSize: 2,\n    },\n  ],\n}\n"
  },
  {
    "path": ".renovate/labels.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  packageRules: [\n    {\n      matchUpdateTypes: [\"major\"],\n      labels: [\"type/major\"],\n    },\n    {\n      matchUpdateTypes: [\"minor\"],\n      labels: [\"type/minor\"],\n    },\n    {\n      matchUpdateTypes: [\"patch\"],\n      labels: [\"type/patch\"],\n    },\n    {\n      matchUpdateTypes: [\"digest\"],\n      labels: [\"type/digest\"],\n    },\n    {\n      matchDatasources: [\"docker\"],\n      addLabels: [\"renovate/container\"],\n    },\n    {\n      matchDatasources: [\"helm\"],\n      addLabels: [\"renovate/helm\"],\n    },\n    {\n      matchManagers: [\"github-actions\"],\n      addLabels: [\"renovate/github-action\"],\n    },\n    {\n      matchDatasources: [\"github-releases\"],\n      addLabels: [\"renovate/github-release\"],\n    },\n  ],\n}\n"
  },
  {
    "path": ".renovate/semanticCommits.json5",
    "content": "{\n  $schema: \"https://docs.renovatebot.com/renovate-schema.json\",\n  packageRules: [\n    {\n      matchUpdateTypes: [\"major\"],\n      semanticCommitType: \"feat\",\n      commitMessagePrefix: \"{{semanticCommitType}}({{semanticCommitScope}})!:\",\n      commitMessageExtra: \"( {{currentVersion}} → {{newVersion}} )\",\n    },\n    {\n      matchUpdateTypes: [\"minor\"],\n      semanticCommitType: \"feat\",\n      commitMessageExtra: \"( {{currentVersion}} → {{newVersion}} )\",\n    },\n    {\n      matchUpdateTypes: [\"patch\"],\n      semanticCommitType: \"fix\",\n      commitMessageExtra: \"( {{currentVersion}} → {{newVersion}} )\",\n    },\n    {\n      matchUpdateTypes: [\"digest\"],\n      semanticCommitType: \"chore\",\n      commitMessageExtra: \"( {{currentDigestShort}} → {{newDigestShort}} )\",\n    },\n    {\n      matchDatasources: [\"docker\"],\n      semanticCommitScope: \"container\",\n      commitMessageTopic: \"image {{depName}}\",\n    },\n    {\n      matchDatasources: [\"helm\"],\n      semanticCommitScope: \"helm\",\n      commitMessageTopic: \"chart {{depName}}\",\n    },\n    {\n      matchManagers: [\"github-actions\"],\n      semanticCommitType: \"ci\",\n      semanticCommitScope: \"github-action\",\n      commitMessageTopic: \"action {{depName}}\",\n    },\n    {\n      matchDatasources: [\"github-releases\"],\n      semanticCommitScope: \"github-release\",\n      commitMessageTopic: \"release {{depName}}\",\n    },\n  ],\n}\n"
  },
  {
    "path": ".sops.yaml",
    "content": "---\n# creation rules are evaluated sequentially, the first match wins\ncreation_rules:\n  # secret files using GCP KMS to encrypt the stored PGP keys\n  - path_regex: kubernetes/clusters/.*/secrets/sops-gpg.encrypted.ya?ml\n    encrypted_regex: ^(data|stringData)$\n    unencrypted-regex: ^(description|metadata)$\n    gcp_kms: projects/raspbernetes/locations/global/keyRings/sops/cryptoKeys/sops-key\n    mac_only_encrypted: true\n  # AGE encrypted Kubernetes secret files\n  - path_regex: kubernetes/.*/.*\\.enc\\.age\\.ya?ml\n    encrypted_regex: ^(data|stringData)$\n    mac_only_encrypted: true\n    age: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n  # AGE encrypted Talos secret files\n  - path_regex: talos/.*/.*\\.enc\\.age\\.ya?ml\n    encrypted_regex: '((?i)(pass|secret($|[^N])|ca|crt|key|token|^data$|^stringData$))'\n    mac_only_encrypted: true\n    age: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n\nstores:\n  yaml:\n    indent: 2\n"
  },
  {
    "path": ".sourceignore",
    "content": "## Used by Fluxv2 Source Controller https://toolkit.fluxcd.io/components/source/gitrepositories/#excluding-files\n\n# Exclude all by default\n/*\n\n# Include the following explicit folder(s)\n!/kubernetes\n\n# Exclude sub-foler(s) and file(s)\n/kubernetes/clusters/**/secrets/\n\n# Include sub-foler(s) and file(s)\n!/kubernetes/clusters/**/secrets/cluster-config.yaml\n!/kubernetes/clusters/**/secrets/cluster-secrets.enc.age.yaml\n!/kubernetes/clusters/**/secrets/github-auth.enc.age.yaml\n"
  },
  {
    "path": ".taskfiles/bootstrap/Taskfile.yaml",
    "content": "---\nversion: '3.41.0'\n\nvars:\n  CLUSTER_ID: '{{.CLUSTER_ID| default \"cluster-00\"}}'\n\nenv:\n  CLUSTER_ID: '{{.CLUSTER_ID}}'\n  ROOT_DIR: '{{.ROOT_DIR}}'\n\ntasks:\n  setup:\n    desc: \"Ensure required CLIs are installed and initialized\"\n    summary: |\n      This task checks if the required dependencies are installed on your system.\n      It then initializes the Helmfile environment to ensure it's ready for use.\n    platforms: [darwin, linux]\n    cmd: helmfile init\n    preconditions:\n      - which helmfile helm kubectl\n    silent: true\n    interactive: true\n\n  bootstrap:\n    desc: \"Bootstrap the FluxCD operator\"\n    summary: |\n      Bootstraps the FluxCD operator in the Kubernetes cluster.\n\n      The command applies the FluxCD operator configuration using Helm.\n      Make sure the necessary environment variables (`CLUSTER_ID`) are set before proceeding.\n    prompt: You're bootstraping FluxCD operator configuration \"kubernetes/clusters/{{.CLUSTER_ID}}\" ... Do you want to continue?\n    deps: [setup, secrets]\n    cmd: helmfile apply --file {{.ROOT_DIR}}/kubernetes/bootstrap/helmfile.yaml --skip-diff-on-install {{.CLI_ARGS}}\n    requires:\n      vars: [CLUSTER_ID]\n    preconditions:\n      - test -f kubernetes/bootstrap/helmfile.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/flux-system/flux-operator/app/values.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/flux-system/flux-instance/app/values.yaml\n    silent: true\n\n  diff:\n    desc: \"Display the differences between the current and desired FluxCD operator configurations\"\n    summary: |\n      This task compares the current state of the FluxCD operator with the desired state specified in the Helmfile.\n      Use this to preview changes before applying them to the cluster.\n    cmds:\n      - echo \"Comparing FluxCD operator configurations... {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}\"\n      - helmfile diff -f {{.ROOT_DIR}}/kubernetes/bootstrap/helmfile.yaml\n    requires:\n      vars: [CLUSTER_ID]\n    preconditions:\n      - test -f kubernetes/bootstrap/helmfile.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/flux-system/flux-operator/app/values.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/flux-system/flux-instance/app/values.yaml\n    silent: true\n\n  secrets:\n    desc: \"Install cluster secrets and configs; Only to be used when updating secrets manually\"\n    env:\n      GOOGLE_APPLICATION_CREDENTIALS: '{{.HOME}}/keys/raspbernetes-d72f2d61e4ac.json'\n    cmds:\n      - kubectl create namespace flux-system --dry-run=client -oyaml | kubectl apply -f -\n      - kubectl create namespace external-secrets --dry-run=client -oyaml | kubectl apply -f -\n      - sops --decrypt \"{{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/sops-gpg.encrypted.yaml\" | kubectl apply -f -\n      - sops --decrypt \"{{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/sops-age.encrypted.yaml\" | kubectl apply -f -\n      - sops --decrypt \"{{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/cluster-secrets.enc.age.yaml\" | kubectl apply -f -\n      - sops --decrypt \"{{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/github-auth.enc.age.yaml\" | kubectl apply -f -\n      - kubectl apply -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/cluster-config.yaml\n    preconditions:\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/sops-gpg.encrypted.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/sops-age.encrypted.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/github-auth.enc.age.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/cluster-secrets.enc.age.yaml\n      - test -f {{.ROOT_DIR}}/kubernetes/clusters/{{.CLUSTER_ID}}/secrets/cluster-config.yaml\n    requires:\n      vars: [CLUSTER_ID]\n    silent: true\n"
  },
  {
    "path": ".taskfiles/core/Taskfile.yaml",
    "content": "---\nversion: '3.41.0'\n\ntasks:\n  gpg:\n    desc: \"Import the public and private gpg keys locally\"\n    cmds:\n      - gpg --import kubernetes/clusters/cluster-00/secrets/.sops.pub.asc\n      - gpg --import <(sops --decrypt \"kubernetes/clusters/cluster-00/secrets/sops-gpg.encrypted.yaml\" | yq e '.data[]' - | base64 -d)\n    status:\n      - gpg --list-secret-keys --keyid-format=long | grep production.owncloud.ai\n\n  lint:\n    desc: \"Example: task core:lint -- --no-warnings\"\n    cmds:\n      - yamllint -c .yamllint.yaml . {{.CLI_ARGS}}\n"
  },
  {
    "path": ".taskfiles/flux/Taskfile.yaml",
    "content": "---\nversion: '3.41.0'\n\ntasks:\n  secrets:\n    desc: \"Install cluster secrets and configs; Only to be used when updating secrets manually\"\n    env:\n      GOOGLE_APPLICATION_CREDENTIALS: ~/raspbernetes-d72f2d61e4ac.json\n    cmds:\n      - cmd: |\n          kubectl create namespace flux-system --dry-run=client -oyaml | kubectl apply -f -\n          sops --decrypt \"kubernetes/clusters/{{.CLUSTER}}/secrets/sops-gpg.encrypted.yaml\" | kubectl apply -f -\n          sops --decrypt \"kubernetes/clusters/{{.CLUSTER}}/secrets/cluster-secrets.enc.age.yaml\" | kubectl apply -f -\n          kubectl apply -f kubernetes/clusters/{{.CLUSTER}}/secrets/cluster-config.yaml\n        silent: false\n\n  tenant:\n    desc: \"Create a new tenant in FluxCD\"\n    cmds:\n      - cmd: |\n          echo \"# This manifest was generated by automation. DO NOT EDIT.\" > kubernetes/tenants/base/{{.TENANT}}/tenant.yaml\n          flux create tenant {{.TENANT}} \\\n            --with-namespace={{.TENANT}}-tenant \\\n            --with-namespace={{.TENANT_NAMESPACE}} \\\n            --export >> kubernetes/tenants/base/{{.TENANT}}/tenant.yaml\n        silent: true\n"
  },
  {
    "path": ".taskfiles/talos/Taskfile.yaml",
    "content": "---\nversion: '3.41.0'\n\nenv:\n  TALOS_DIR: \"talos/generated\"\n\ntasks:\n  config:\n    desc: \"Decrypt and Loads TALOSCONFIG into $HOME directory\"\n    cmds:\n      - sops -d {{.TALOS_DIR}}/talosconfig.enc.yaml > \"$HOME/.talos/config\"\n"
  },
  {
    "path": ".yamllint.yaml",
    "content": "---\n# This configuration serves as a base for the entire repo\nignore: |\n  *.encrypted.yaml\n  *.enc.yaml\n  **/kubernetes/clusters/**\n  talos/\n  .github/workflows/\n  .taskfiles/\n\nextends: default\nrules:\n  # Disallow duplicate dictionary keys\n  key-duplicates: enable\n\n  # Require consistent indentation\n  indentation:\n    spaces: 2\n    indent-sequences: consistent\n    check-multi-line-strings: false\n\n  # Line length\n  line-length:\n    max: 240\n    level: warning\n    allow-non-breakable-words: true\n    allow-non-breakable-inline-mappings: true\n\n  # Trailing spaces\n  trailing-spaces: enable\n\n  # Final newline at end of file\n  new-line-at-end-of-file: enable\n\n  # Allow specific syntax for boolean values\n  truthy:\n    allowed-values: ['true', 'false', 'on', 'off', 'yes', 'no']\n    check-keys: false\n\n  # Spacing for comments\n  comments:\n    require-starting-space: true\n    min-spaces-from-content: 1\n\n  # Consistent spacing in braces — enforce { foo: bar } not {foo: bar}\n  braces:\n    min-spaces-inside: 1\n    max-spaces-inside: 1\n    min-spaces-inside-empty: 0\n    max-spaces-inside-empty: 0\n\n  # Consistent spacing in brackets\n  brackets:\n    min-spaces-inside: 0\n    max-spaces-inside: 0\n    min-spaces-inside-empty: 0\n    max-spaces-inside-empty: 0\n\n  # Consistent document start/end markers\n  document-start:\n    present: true\n  document-end:\n    present: false\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Repository Overview\n\nThis is a Kubernetes GitOps repository for a personal homelab cluster managed with FluxCD and Talos Linux. The cluster follows enterprise-grade security and observability practices, showcasing CNCF ecosystem tools.\n\n## Architecture\n\n- **Operating System**: Talos Linux (minimal, immutable Kubernetes OS)\n- **GitOps**: FluxCD with Flux Operator for declarative cluster management\n- **Container Runtime**: containerd\n- **Networking**: Cilium CNI with Istio service mesh\n- **Storage**: Rook-Ceph, OpenEBS, democratic-csi for container-attached storage\n- **Monitoring**: Prometheus, Grafana, Loki, Jaeger, Thanos for observability\n- **Security**: Kyverno, OPA Gatekeeper for policy management, Falco & Tetragon for runtime security\n- **Load Balancing**: MetalLB for bare metal load balancing\n- **Chaos Engineering**: Litmus for chaos testing\n\n## Directory Structure\n\n```\n├── kubernetes/                       # Kubernetes manifests and configurations\n│   ├── apps/\n│   │   ├── base/                     # Base application configurations (DRY principle)\n│   │   │   └── [system-name]/        # e.g., observability, kube-system, home-system\n│   │   │       ├── [app-name]/\n│   │   │       │   ├── app/          # HelmRelease, OCIRepository, secrets, values\n│   │   │       │   └── ks.yaml       # Flux Kustomization with dependencies\n│   │   │       ├── namespace.yaml\n│   │   │       └── kustomization.yaml\n│   │   └── overlays/\n│   │       └── cluster-00/           # Cluster-specific overrides\n│   ├── bootstrap/\n│   │   └── helmfile.yaml             # Bootstrap Flux Operator and dependencies\n│   ├── clusters/\n│   │   └── cluster-00/\n│   │       ├── flux-system/          # Flux Operator and FluxInstance configs\n│   │       ├── secrets/              # Cluster secrets (SOPS encrypted)\n│   │       └── ks.yaml               # Root Kustomization\n│   ├── components/\n│   │   └── common/alerts/            # Shared monitoring alerts\n│   └── tenants/                      # Multi-tenant configurations\n├── talos/                            # Talos Linux configuration files\n│   ├── generated/                    # Generated Talos configs (encrypted)\n│   ├── integrations/                 # Cilium, cert-approver integrations\n│   └── patches/                      # iSCSI, metrics patches\n├── terraform/                        # Infrastructure as Code\n│   ├── cloudflare/                   # Cloudflare DNS/CDN configuration\n│   └── gcp/                          # GCP KMS, Thanos storage, Velero backups\n├── .taskfiles/                       # Task automation definitions\n└── docs/                             # Documentation\n```\n\n## Common Commands\n\n### Task Management (Primary Build System)\nThe repository uses [Task](https://taskfile.dev) for automation. All commands should be run via `task`:\n\n```bash\n# FluxCD Operations\ntask flux:bootstrap          # Bootstrap Flux Operator via Helmfile\ntask flux:secrets           # Install cluster secrets (SOPS decrypt + apply)\ntask fluxcd:bootstrap       # Alternative bootstrap path\ntask fluxcd:diff            # Preview FluxCD operator changes\n\n# Talos Operations\ntask talos:config           # Decrypt and load talosconfig to ~/.talos/config\n\n# Core Operations\ntask core:gpg               # Import SOPS PGP keys\ntask core:lint              # Run yamllint\n\n# View available tasks\ntask --list\n```\n\n**Important Variables:**\n- `CLUSTER`: cluster-00 (default cluster ID)\n- `GITHUB_USER`: xunholy\n- `GITHUB_REPO`: k8s-gitops\n- `GITHUB_BRANCH`: main\n\n### Pre-commit Hooks\nThe repository uses pre-commit for code quality:\n```bash\npre-commit run --all-files   # Run all pre-commit hooks\n```\n\nActive hooks include:\n- YAML/JSON/TOML validation\n- yamllint (with `.yamllint.yaml` config)\n- shellcheck for shell scripts\n- Trailing whitespace and EOF fixes\n\n### Secret Management\nSecrets are encrypted using [SOPS](https://github.com/mozilla/sops) with dual encryption (PGP + GCP KMS):\n```bash\n# Edit encrypted files (automatically decrypts/encrypts)\nsops path/to/file.enc.yaml\n\n# Decrypt for viewing only\nsops -d path/to/file.enc.yaml\n```\n\n**SOPS Configuration:**\n- **PGP Key**: `0635B8D34037A9453003FB7B93CAA682FF4C9014`\n- **Age Key**: `age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t`\n- **GCP KMS**: Used for stored PGP keys\n- Encrypted files use `.enc.yaml` or `.enc.age.yaml` suffix\n\n## Key Technologies & Patterns\n\n### GitOps with FluxCD\nThis repository uses **Flux Operator** instead of traditional `flux bootstrap`:\n- **FluxInstance CRDs**: Declaratively manage FluxCD components\n- **OCIRepository**: Used for Helm charts instead of HelmRepository (e.g., `oci://ghcr.io/prometheus-community/charts`)\n- **Kustomizations**: Define manifest application with SOPS decryption, post-build substitution, and dependency chains\n- **HelmReleases**: Reference charts via `chartRef` pointing to OCIRepository\n- **Root Kustomization**: Located at `kubernetes/clusters/cluster-00/ks.yaml`\n\n### Application Deployment Pattern\nEach application follows this structure:\n1. **Base configuration** in `kubernetes/apps/base/[system-name]/[app-name]/`:\n   - `app/helmrelease.yaml`: Helm release definition\n   - `app/ocirepository.yaml`: Chart source\n   - `app/secret.enc.yaml`: Encrypted secrets\n   - `app/values.yaml`: Helm values\n   - `ks.yaml`: Flux Kustomization with `dependsOn`, SOPS settings, substitutions\n\n2. **Cluster overlays** in `kubernetes/apps/overlays/cluster-00/`: Cluster-specific customizations using Kustomize patches\n\n3. **System categories**: Apps organized into logical systems:\n   - `kube-system`: Core Kubernetes (Cilium, metrics-server, reflector)\n   - `network-system`: Networking (cert-manager, external-dns, oauth2-proxy, dex)\n   - `observability`: Monitoring (Prometheus, Grafana, Loki, Jaeger, Thanos)\n   - `security-system`: Security (Kyverno, Falco, Gatekeeper, Crowdsec)\n   - `istio-system` & `istio-ingress`: Service mesh\n   - `home-system`: Home automation & media\n   - `rook-ceph`: Storage\n\n### HelmRelease Global Defaults\nAll HelmReleases are patched with these defaults via Kustomization:\n```yaml\ninstall:\n  crds: CreateReplace\n  createNamespace: true\n  replace: true\n  strategy: RetryOnFailure\n  timeout: 10m\nrollback:\n  recreate: true\n  force: true\n  cleanupOnFail: true\nupgrade:\n  cleanupOnFail: true\n  crds: CreateReplace\n  remediation:\n    remediateLastFailure: true\n    retries: 3\n    strategy: rollback\n```\n\n### Security Practices\n- **Dual encryption**: SOPS with PGP (primary) + GCP KMS backup\n- **Never commit unencrypted secrets**: All secrets use `.enc.yaml` suffix\n- **Policy enforcement**: Kyverno & OPA Gatekeeper\n- **Runtime security**: Falco & Tetragon\n- **Pod security labels**: Applied to all namespaces\n- **Immutable OS**: Talos Linux minimal attack surface\n\n## Development Workflow\n\n### Bootstrap New Cluster\n```bash\n# 1. Set environment variables (CLUSTER_ID defaults to cluster-00)\n# 2. Bootstrap Flux Operator\ntask fluxcd:bootstrap  # Installs flux-operator, flux-instance, cert-manager, kustomize-mutating-webhook\n\n# 3. Install cluster secrets\ntask flux:secrets      # Decrypts and applies sops-gpg, sops-age, cluster-secrets, github-auth, cluster-config\n\n# 4. Configure Talos\ntask talos:config      # Decrypts talosconfig to ~/.talos/config\n```\n\n### Making Changes to Applications\n1. **Edit base configuration** in `kubernetes/apps/base/[system-name]/[app-name]/`\n2. **Use overlays** for cluster-specific customization in `kubernetes/apps/overlays/cluster-00/`\n3. **Follow naming conventions**:\n   - `ks.yaml`: Flux Kustomization resources\n   - `kustomization.yaml`: Kustomize configuration\n   - `*.enc.yaml`: SOPS encrypted files\n   - `helmrelease.yaml`: Helm release definitions\n   - `ocirepository.yaml`: OCI repository sources\n4. **Ensure secrets are encrypted** before committing (use `sops` command)\n5. **Run pre-commit hooks**: `pre-commit run --all-files`\n6. **FluxCD auto-reconciles** from main branch after push\n\n### Adding New Applications\n1. Create directory structure: `kubernetes/apps/base/[system-name]/[app-name]/`\n2. Add `app/` directory with:\n   - `helmrelease.yaml` (with `chartRef` to OCIRepository)\n   - `ocirepository.yaml` (chart source)\n   - `values.yaml` (Helm values)\n   - `secret.enc.yaml` (if needed, encrypted with SOPS)\n   - `kustomization.yaml`\n3. Create `ks.yaml` with:\n   - `dependsOn` for dependency chain\n   - `decryption` for SOPS secrets\n   - `postBuild.substituteFrom` for ConfigMap/Secret references\n4. Add to parent `kustomization.yaml`\n5. Create overlay if cluster-specific customization needed\n\n## Important Patterns & Conventions\n\n### File Naming\n- `ks.yaml`: Flux Kustomization resources (defines how to apply manifests)\n- `kustomization.yaml`: Kustomize configuration (defines what resources to include)\n- `*.enc.yaml`: SOPS-encrypted with PGP\n- `*.enc.age.yaml`: SOPS-encrypted with Age\n- `helmfile.yaml`: Helmfile configurations (used in bootstrap)\n- `helmrelease.yaml`: Helm release definitions\n- `ocirepository.yaml`: OCI repository sources for Helm charts\n- `namespace.yaml`: Namespace definitions with pod security labels\n\n### Kustomization Labels\n- `substitution.flux/enabled=true`: Enables SOPS decryption and variable substitution\n- Patches applied globally to all Kustomizations for HelmRelease defaults\n\n### Namespace Conventions\nLabels applied to namespaces:\n- `pod-security.kubernetes.io/enforce: privileged` (or `restricted`/`baseline`)\n- `goldilocks.fairwinds.com/enabled: \"true\"` (monitoring)\n- `kustomize.toolkit.fluxcd.io/prune: disabled` (on flux-system)\n\n### Dependency Management\nFlux Kustomizations use `dependsOn` to establish deployment order:\n```yaml\ndependsOn:\n  - name: cert-manager\n    namespace: flux-system\n```\n\n## Important Notes\n\n- **Cluster ID**: \"cluster-00\" is the default cluster identifier\n- **Branch**: `main` is the primary branch (auto-reconciled by FluxCD)\n- **Talos configs**: Stored encrypted in `talos/generated/`\n- **Bootstrap method**: Uses Flux Operator (not traditional `flux bootstrap`)\n- **Chart sources**: Uses OCIRepository instead of HelmRepository\n- **Yamllint config**: Line length warning at 240 characters, 2-space indentation\n- **Renovate automation**: Auto-merge enabled for digests, ignores encrypted files\n- **Multi-cluster ready**: Designed with overlay pattern for multiple clusters\n- **Enterprise patterns**: Production-grade GitOps implementation showcasing CNCF ecosystem\n\n## External Dependencies\n\n- **Cloudflare**: DNS management and CDN services\n- **Google Cloud Platform**:\n  - GCP KMS for SOPS encryption\n  - Google Cloud Storage for Thanos long-term metrics storage\n  - Google Cloud Storage for Velero backups\n  - OAuth for authentication\n- **GitHub**: Source control, authentication, and OCI registry for Helm charts\n- **SOPS/age**: Secret encryption (requires PGP and/or age key setup)\n- **Task**: Task runner (must be installed locally)\n- **Helmfile**: Used for bootstrap process\n- **Let's Encrypt**: Certificate generation for secure communication\n- **NextDNS**: Malware protection and ad-blocking\n- **UptimeRobot**: Service monitoring\n\n## Troubleshooting with Flux MCP\n\nThis repository includes Cursor rules for troubleshooting Flux resources using the `flux-operator-mcp` tools. Key troubleshooting workflows:\n\n### Analyzing HelmReleases\n1. Check helm-controller status with `get_flux_instance`\n2. Get HelmRelease resource and analyze spec, status, inventory, events\n3. Check `valuesFrom` ConfigMaps and Secrets\n4. Verify source (OCIRepository) status\n5. Analyze managed resources from inventory\n6. Check logs if resources are failing\n\n### Analyzing Kustomizations\n1. Check kustomize-controller status with `get_flux_instance`\n2. Get Kustomization resource and analyze spec, status, inventory, events\n3. Check `substituteFrom` ConfigMaps and Secrets\n4. Verify source (GitRepository/OCIRepository) status\n5. Analyze managed resources from inventory\n\n### Comparing Resources Across Clusters\nUse `get_kubernetes_contexts` and `set_kubernetes_context` to switch between clusters, then compare resource specs and status.\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n\n# My Own Cloud\n\n_... managed with Flux, Renovate and GitHub Actions_\n\n</div>\n\n<div align=\"center\">\n\n[![Discord](https://img.shields.io/discord/673534664354430999?style=for-the-badge&label=discord&logo=discord&logoColor=white&color=blue)](https://discord.gg/home-operations)&nbsp;&nbsp;\n[![Kubernetes](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fkubernetes_version&style=for-the-badge&logo=kubernetes&logoColor=white&color=blue)](https://kubernetes.io/)&nbsp;&nbsp;\n[![Talos](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Ftalos_version&style=for-the-badge&logo=talos&logoColor=white&color=blue)](https://talos.dev)&nbsp;&nbsp;\n[![FluxCD](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fflux_version&style=for-the-badge&logo=flux&logoColor=white&color=blue)](https://fluxcd.io/)&nbsp;&nbsp;\n\n</div>\n\n<div align=\"center\">\n\n[![Age-Days](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fcluster_age_days&style=flat-square&label=Age)](https://github.com/kashalls/kromgo)&nbsp;&nbsp;\n[![Uptime-Days](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fcluster_uptime_days&style=flat-square&label=Uptime)](https://github.com/kashalls/kromgo)&nbsp;&nbsp;\n[![Node-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fcluster_node_count&style=flat-square&label=Nodes)](https://github.com/kashalls/kromgo)&nbsp;&nbsp;\n[![Pod-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fcluster_pod_count&style=flat-square&label=Pods)](https://github.com/kashalls/kromgo)&nbsp;&nbsp;\n[![CPU-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fcluster_cpu_usage&style=flat-square&label=CPU)](https://github.com/kashalls/kromgo)&nbsp;&nbsp;\n[![Memory-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.owncloud.ai%2Fcluster_memory_usage&style=flat-square&label=Memory)](https://github.com/kashalls/kromgo)&nbsp;&nbsp;\n\n</div>\n\n# 🍼 Overview\n\nThis educational project is designed to provide a hands-on learning experience for mastering Kubernetes cluster configurations and best practices. The repository showcases a declarative implementation of a Kubernetes cluster, following GitOps principles that can be utilized with a variety of tools and workflows.\n\nThe main goal of this project is to demonstrate best practices for implementing enterprise-grade security, observability, and comprehensive cluster configuration management using GitOps in a Kubernetes environment, while fostering learning and growth in the Kubernetes community.\n\nThis repository leverages a range of cutting-edge open-source tools and platforms, forming a comprehensive technology stack that demonstrates the power of the [CNCF ecosystem](https://landscape.cncf.io/).\n\n## 📖 Table of contents\n\n- [🍼 Overview](#-overview)\n  - [📖 Table of contents](#-table-of-contents)\n  - [🔧 Hardware](#-hardware)\n  - [☁️ Cloud Services](#️-cloud-services)\n  - [🖥️ Technology Stack](#️-technology-stack)\n  - [🤖 Automation](#-automation)\n  - [🤝 Acknowledgments](#-acknowledgments)\n  - [👥 Contributing](#-contributing)\n    - [🚫 Code of Conduct](#-code-of-conduct)\n    - [💡 Reporting Issues and Requesting Features](#-reporting-issues-and-requesting-features)\n  - [📄 License](#-license)\n\n## 🔧 Hardware\n\n| Device | Description | Quantity | CPU | RAM | Storage | Architecture | Operating System |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| [Ubiquiti UDM-Pro-Max](https://ui.com/us/en/cloud-gateways/dream-machine-pro-max) | Router/Gateway | 1 | - | - | 8TB | - | UniFi OS |\n| [Ubiquiti USW-Pro-Max-48-PoE](https://ui.com/switching/pro-max-48-poe) | Network Switch | 1 | - | - | - | - | UniFi OS |\n| [Asus NUC 14 Pro](https://www.asus.com/displays-desktops/nucs/nuc-mini-pcs/asus-nuc-14-pro/) | Kubernetes Nodes | 3 | 14 cores | 48GB | 1TB NVMe + 1TB SSD | AMD64 | [Talos Linux](https://www.talos.dev/) |\n| NAS | Storage | 1 | 8 cores | 16GB | 48TB | AMD64 | [TrueNAS](https://www.truenas.com/) |\n| [JetKVM](https://jetkvm.com/) | Remote KVM | 3 | - | - | - | - | - |\n\n<details>\n<summary>Decommissioned Hardware</summary>\n\n| Device                                                                                 | Description        | Quantity | CPU      | RAM   | Storage | Architecture | Operating System                      |\n| -------------------------------------------------------------------------------------- | ------------------ | -------- | -------- | ----- | ------- | ------------ | ------------------------------------- |\n| [Protectli FW6E](https://protectli.com/product/fw6e/)                                  | Router             | 1        | 4 Cores  | 16GB  | -       | AMD64        | [VyOs](https://vyos.io/)              |\n| [Protectli VP2410](https://protectli.com/product/vp2410/)                             | Kubernetes Node(s) | 3        | 4 Cores  | 8GB   | -       | AMD64        | [Talos Linux](https://www.talos.dev/) |\n| [Protectli FW2B](https://protectli.com/product/fw2b/)                                  | Kubernetes Node(s) | 3        | 2 Cores  | 8GB   | -       | AMD64        | [Talos Linux](https://www.talos.dev/) |\n| [Raspberry Pi 4 Model B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) | Kubernetes Node(s) | 4        | 4 Cores  | 8GB   | -       | ARM64        | [Talos Linux](https://www.talos.dev/) |\n| [Rock Pi 4 Model C](https://rockpi.org/rockpi4#)                                       | Kubernetes Node(s) | 6        | 4 Cores  | 4GB   | -       | ARM64        | [Talos Linux](https://www.talos.dev/) |\n\n</details>\n\n## ☁️ Cloud Services\n\nAlthough I manage most of my infrastructure and workloads on my own, there are specific components of my setup that rely on cloud services.\n\n| Service                                   | Description                                                                                                                     | Cost (AUD)     |\n| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------------- |\n| [Cloudflare](https://www.cloudflare.com/) | I use Cloudflare in my home network for DNS management and to secure my domain with Cloudflare's services.                      | ~$69/yr        |\n| [GCP](https://cloud.google.com/)          | I use Google Cloud Platform (GCP) to manage backups using Google Cloud Storage (GCS) and employ GCP's OAuth for authentication. | ~20/yr         |\n| [GitHub](https://github.com/)             | I use GitHub for code management and version control, enabling seamless collaboration in addition to OAuth for authentication   | Free\n| [Lets Encrypt](https://letsencrypt.org/)  | I use Let's Encrypt to generate certificates for secure communication within my network.                                        | Free           |\n|                                           |                                                                                                                                 | Total: ~$35/mo |\n\n## 🖥️ Technology Stack\n\nThe below showcases the collection of open-source solutions currently implemented in the cluster. Each of these components has been meticulously documented, and their deployment is managed using FluxCD, which adheres to GitOps principles.\n\nThe Cloud Native Computing Foundation (CNCF) has played a crucial role in the development and popularization of many of these tools, driving the adoption of cloud-native technologies and enabling projects like this one to thrive.\n\n|                                                                                                                                | Name                                                            | Description                                                                                                    |\n| ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/kubernetes/icon/color/kubernetes-icon-color.svg\">       | [Kubernetes](https://kubernetes.io/)                            | An open-source system for automating deployment, scaling, and management of containerized applications          |\n| <img width=\"32\" src=\"https://www.talos.dev/favicon.svg\">                                                                      | [Talos Linux](https://www.talos.dev/)                           | Minimal, immutable Linux OS designed for Kubernetes                                                            |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/flux/icon/color/flux-icon-color.svg\">                  | [FluxCD](https://fluxcd.io/)                                    | GitOps continuous delivery for Kubernetes                                                                      |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/helm/icon/color/helm-icon-color.svg\">                  | [Helm](https://helm.sh)                                         | The Kubernetes package manager                                                                                 |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/cilium/icon/color/cilium_icon-color.svg\">              | [Cilium](https://cilium.io/)                                    | eBPF-based CNI providing networking, security, and observability                                               |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/envoy/icon/color/envoy-icon-color.svg\">                | [Envoy Gateway](https://gateway.envoyproxy.io/)                 | Kubernetes Gateway API implementation built on Envoy proxy                                                     |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/containerd/icon/color/containerd-icon-color.svg\">      | [containerd](https://containerd.io/)                            | Industry-standard container runtime integrated with Talos Linux                                                |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/coredns/icon/color/coredns-icon-color.svg\">            | [CoreDNS](https://coredns.io/)                                  | Flexible, plugin-based DNS server for Kubernetes service discovery                                             |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/rook/icon/color/rook-icon-color.svg\">                  | [Rook-Ceph](https://rook.io/)                                   | Cloud-native storage orchestration for Kubernetes using Ceph                                                   |\n| <img width=\"32\" src=\"https://raw.githubusercontent.com/backube/volsync/main/docs/media/volsync.svg\">                          | [Volsync](https://volsync.readthedocs.io/)                      | Asynchronous data replication for Kubernetes persistent volumes                                                |\n| <img width=\"32\" src=\"https://avatars.githubusercontent.com/u/99631794\">                                                       | [Spegel](https://github.com/spegel-org/spegel)                  | Stateless cluster-local OCI registry mirror                                                                    |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/prometheus/icon/color/prometheus-icon-color.svg\">      | [Prometheus](https://prometheus.io)                              | Monitoring system and time series database                                                                     |\n| <img width=\"32\" src=\"https://grafana.com/static/img/menu/grafana2.svg\">                                                       | [Grafana](https://grafana.com)                                  | Analytics and monitoring dashboards                                                                            |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/cert-manager/icon/color/cert-manager-icon-color.svg\">  | [cert-manager](https://cert-manager.io/)                        | X.509 certificate management for Kubernetes                                                                    |\n| <img width=\"32\" src=\"https://raw.githubusercontent.com/external-secrets/external-secrets/main/assets/eso-logo-large.png\">      | [External Secrets](https://external-secrets.io/)                 | Synchronize secrets from external APIs (1Password) into Kubernetes                                             |\n| <img width=\"32\" src=\"https://raw.githubusercontent.com/kubernetes-sigs/external-dns/master/docs/img/external-dns.png\">         | [ExternalDNS](https://github.com/kubernetes-sigs/external-dns)  | Automatically manage DNS records from Kubernetes resources                                                     |\n| <img width=\"32\" src=\"https://github.com/cncf/artwork/raw/main/projects/dex/icon/color/dex-icon-color.svg\">                    | [Dex](https://github.com/dexidp/dex)                            | OpenID Connect identity provider for authentication                                                            |\n| <img width=\"32\" src=\"https://raw.githubusercontent.com/oauth2-proxy/oauth2-proxy/master/docs/static/img/logos/OAuth2_Proxy_icon.svg\"> | [oauth2-proxy](https://oauth2-proxy.github.io/oauth2-proxy/)    | Reverse proxy providing authentication with external OAuth2 providers                                          |\n| <img width=\"32\" src=\"https://avatars.githubusercontent.com/u/314135\">                                                         | [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) | Secure outbound-only tunnel for exposing services without public IPs             |\n\n## 🤖 Automation\n\nThis repository is automatically managed by [Renovate](https://renovatebot.com/). Renovate will keep all of the container images within this repository up to date automatically. It can also be configured to keep Helm chart dependencies up to date as well.\n\n## 🤝 Acknowledgments\n\nA special thank you to everyone in the [Home Operation Discord](https://discord.com/invite/home-operations) community for their valuable contributions and time. Much of the inspiration for my cluster comes from fellow enthusiasts who have shared their own clusters under the k8s-at-home GitHub topic.\n\nAlso I extend heartfelt thanks to all CNCF contributors for their dedication and expertise, as their collective efforts have been vital in driving innovation and success within the cloud-native ecosystem.\n\nFor more ideas on deploying applications or discovering new possibilities, be sure to explore the [kubesearch.dev](https://kubesearch.dev/) search.\n\n## 👥 Contributing\n\nOur project welcomes contributions from any member of our community. To get started contributing, please see our [Contributor Guide](.github/CONTRIBUTING.md).\n\n### 🚫 Code of Conduct\n\nBy participating in this project, you are expected to uphold the project's [**Code of Conduct**](.github/CODE_OF_CONDUCT.md). Please report any unacceptable behavior to the repository maintainer.\n\n### 💡 Reporting Issues and Requesting Features\n\nIf you encounter any issues or would like to request new features, please create an issue on the repository's issue tracker. When reporting issues, include as much information as possible, such as error messages, logs, and steps to reproduce the issue.\n\nThank you for your interest in contributing to this project! Your contributions help make it better for everyone.\n\n## 📄 License\n\nThis repository is [Apache 2.0 licensed](./LICENSE)\n"
  },
  {
    "path": "Taskfile.yml",
    "content": "---\n# yaml-language-server: $schema=https://taskfile.dev/schema.json\nversion: '3.41.0'\n\nvars:\n  CLUSTER: cluster-00\n  GITHUB_USER: xunholy\n  GITHUB_REPO: k8s-gitops\n  GITHUB_BRANCH: main\n\nincludes:\n  fluxcd: .taskfiles/bootstrap\n  core: .taskfiles/core\n  flux: .taskfiles/flux\n  talos: .taskfiles/talos\n\ntasks:\n  flux:\n    desc: \"Install Fluxv2 into a cluster\"\n    cmds:\n      - task: flux:secrets\n      - task: flux:bootstrap\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>owncloud.ai — Cloud Native Homelab</title>\n  <meta name=\"description\" content=\"A production-grade homelab powered by Talos Linux, FluxCD, and the CNCF ecosystem. Enterprise security, observability, and GitOps — all running from home.\" />\n  <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n  <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n  <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap\" rel=\"stylesheet\" />\n  <style>\n    /* ─── Reset & Base ─────────────────────────────────────────── */\n    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n    html { scroll-behavior: smooth; }\n\n    body {\n      font-family: 'Inter', system-ui, sans-serif;\n      background: #050510;\n      color: #c8ccd8;\n      overflow-x: hidden;\n      min-height: 100vh;\n    }\n\n    /* Grain overlay */\n    body::after {\n      content: '';\n      position: fixed;\n      inset: 0;\n      pointer-events: none;\n      z-index: 9999;\n      opacity: 0.025;\n      background-image: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E\");\n      background-repeat: repeat;\n      background-size: 128px 128px;\n    }\n\n    /* ─── Three.js Canvas ──────────────────────────────────────── */\n    #hero-canvas {\n      position: fixed;\n      top: 0; left: 0;\n      width: 100%; height: 100%;\n      z-index: 0;\n      pointer-events: none;\n    }\n\n    /* Radial glow */\n    .bg-glow {\n      position: fixed;\n      z-index: 0;\n      pointer-events: none;\n      width: 700px;\n      height: 700px;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -40%);\n      background: radial-gradient(circle, rgba(124,58,237,0.14) 0%, rgba(79,70,229,0.07) 40%, transparent 70%);\n      filter: blur(40px);\n      animation: glowPulse 8s ease-in-out infinite alternate;\n    }\n\n    @keyframes glowPulse {\n      0%   { opacity: 0.6; transform: translate(-50%, -40%) scale(1); }\n      100% { opacity: 1;   transform: translate(-50%, -40%) scale(1.1); }\n    }\n\n    /* Scroll-driven darkening overlay */\n    #scroll-darken {\n      position: fixed;\n      inset: 0;\n      background: #050510;\n      opacity: 0;\n      pointer-events: none;\n      z-index: 1;\n      transition: opacity 0.1s linear;\n    }\n\n    /* ─── Glass Utilities ──────────────────────────────────────── */\n    .frost {\n      background: rgba(255, 255, 255, 0.04);\n      backdrop-filter: blur(24px) saturate(140%);\n      -webkit-backdrop-filter: blur(24px) saturate(140%);\n      border: 1px solid rgba(255, 255, 255, 0.08);\n      border-radius: 20px;\n    }\n\n    .frost-light {\n      background: rgba(255, 255, 255, 0.03);\n      backdrop-filter: blur(16px) saturate(120%);\n      -webkit-backdrop-filter: blur(16px) saturate(120%);\n      border: 1px solid rgba(255, 255, 255, 0.06);\n      border-radius: 16px;\n    }\n\n    /* ─── Navbar ───────────────────────────────────────────────── */\n    .nav {\n      position: fixed;\n      top: 0; left: 0; right: 0;\n      z-index: 500;\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      padding: 20px 40px;\n      transition: padding 0.3s ease, background 0.3s ease, border-color 0.3s ease;\n      border-bottom: 1px solid transparent;\n    }\n\n    .nav.scrolled {\n      padding: 14px 40px;\n      background: rgba(5, 5, 16, 0.82);\n      backdrop-filter: blur(20px) saturate(140%);\n      -webkit-backdrop-filter: blur(20px) saturate(140%);\n      border-bottom: 1px solid rgba(255, 255, 255, 0.07);\n    }\n\n    .nav-logo {\n      font-size: 1.15rem;\n      font-weight: 800;\n      color: #fff;\n      text-decoration: none;\n      letter-spacing: -0.02em;\n      user-select: none;\n    }\n\n    .nav-links {\n      display: flex;\n      align-items: center;\n      gap: 32px;\n      list-style: none;\n    }\n\n    .nav-links a {\n      color: #9097a8;\n      text-decoration: none;\n      font-size: 0.875rem;\n      font-weight: 500;\n      transition: color 0.2s;\n    }\n\n    .nav-links a:hover { color: #fff; }\n\n    .nav-right {\n      display: flex;\n      align-items: center;\n      gap: 0;\n    }\n\n    .nav-gh {\n      display: flex;\n      align-items: center;\n      gap: 7px;\n      padding: 8px 14px;\n      border: 1px solid rgba(255,255,255,0.10);\n      border-radius: 10px 0 0 10px;\n      color: #c8ccd8;\n      text-decoration: none;\n      font-size: 0.8rem;\n      font-weight: 600;\n      transition: border-color 0.3s, background 0.3s, color 0.3s;\n      background: rgba(255,255,255,0.04);\n    }\n\n    .nav-gh:hover {\n      border-color: rgba(255,255,255,0.22);\n      background: rgba(255,255,255,0.08);\n      color: #fff;\n    }\n\n    .nav-gh svg { width: 16px; height: 16px; flex-shrink: 0; }\n\n    .nav-stars {\n      display: flex;\n      align-items: center;\n      gap: 5px;\n      padding: 8px 14px;\n      border: 1px solid rgba(255,255,255,0.10);\n      border-left: 1px solid rgba(255,255,255,0.06);\n      border-radius: 0 10px 10px 0;\n      color: #c8ccd8;\n      text-decoration: none;\n      font-size: 0.8rem;\n      font-weight: 600;\n      background: rgba(255,255,255,0.04);\n      transition: border-color 0.3s, background 0.3s, color 0.3s;\n    }\n\n    .nav-stars:hover {\n      border-color: rgba(255,255,255,0.22);\n      background: rgba(255,255,255,0.08);\n      color: #fff;\n    }\n\n    .nav-stars svg { width: 12px; height: 12px; flex-shrink: 0; color: #e3b341; }\n\n    /* Hamburger */\n    .nav-hamburger {\n      display: none;\n      flex-direction: column;\n      gap: 5px;\n      cursor: pointer;\n      padding: 6px;\n      background: none;\n      border: none;\n    }\n\n    .nav-hamburger span {\n      display: block;\n      width: 22px;\n      height: 2px;\n      background: #c8ccd8;\n      border-radius: 2px;\n      transition: transform 0.25s, opacity 0.25s;\n    }\n\n    .nav-hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }\n    .nav-hamburger.open span:nth-child(2) { opacity: 0; }\n    .nav-hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }\n\n    .nav-mobile {\n      display: none;\n      position: fixed;\n      top: 64px; left: 0; right: 0;\n      background: rgba(5, 5, 16, 0.96);\n      backdrop-filter: blur(20px);\n      -webkit-backdrop-filter: blur(20px);\n      border-bottom: 1px solid rgba(255,255,255,0.07);\n      padding: 24px 32px;\n      z-index: 499;\n      flex-direction: column;\n      gap: 20px;\n    }\n\n    .nav-mobile.open { display: flex; }\n\n    .nav-mobile a {\n      color: #c8ccd8;\n      text-decoration: none;\n      font-size: 1rem;\n      font-weight: 500;\n      transition: color 0.2s;\n    }\n\n    .nav-mobile a:hover { color: #fff; }\n\n    /* ─── Buttons ──────────────────────────────────────────────── */\n    .btn-primary {\n      display: inline-flex;\n      align-items: center;\n      gap: 8px;\n      padding: 13px 28px;\n      background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n      color: #fff;\n      border: none;\n      border-radius: 10px;\n      font-size: 0.925rem;\n      font-weight: 600;\n      text-decoration: none;\n      cursor: pointer;\n      position: relative;\n      overflow: hidden;\n      transition: opacity 0.2s, transform 0.2s, box-shadow 0.2s;\n      box-shadow: 0 4px 24px rgba(99,102,241,0.35);\n    }\n\n    .btn-primary:hover {\n      opacity: 0.92;\n      transform: translateY(-1px);\n      box-shadow: 0 8px 32px rgba(99,102,241,0.45);\n    }\n\n    .btn-primary svg { width: 16px; height: 16px; flex-shrink: 0; }\n\n    /* Wave sweep animation */\n    .btn-wave::after {\n      content: '';\n      position: absolute;\n      top: 0; left: -100%;\n      width: 60%;\n      height: 100%;\n      background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);\n      transform: skewX(-20deg);\n      animation: btn-wave-sweep 3s ease-in-out infinite;\n    }\n\n    @keyframes btn-wave-sweep {\n      0%   { left: -100%; }\n      50%  { left: 150%; }\n      100% { left: 150%; }\n    }\n\n    .btn-ghost {\n      display: inline-flex;\n      align-items: center;\n      gap: 8px;\n      padding: 13px 28px;\n      background: rgba(255,255,255,0.05);\n      color: #c8ccd8;\n      border: 1px solid rgba(255,255,255,0.12);\n      border-radius: 10px;\n      font-size: 0.925rem;\n      font-weight: 600;\n      text-decoration: none;\n      cursor: pointer;\n      transition: background 0.2s, border-color 0.2s, color 0.2s, transform 0.2s;\n    }\n\n    .btn-ghost:hover {\n      background: rgba(255,255,255,0.09);\n      border-color: rgba(255,255,255,0.22);\n      color: #fff;\n      transform: translateY(-1px);\n    }\n\n    .btn-ghost svg { width: 16px; height: 16px; flex-shrink: 0; }\n\n    /* ─── Accent gradient text ─────────────────────────────────── */\n    .accent {\n      background: linear-gradient(135deg, #6366f1 0%, #a78bfa 60%, #c4b5fd 100%);\n      -webkit-background-clip: text;\n      -webkit-text-fill-color: transparent;\n      background-clip: text;\n    }\n\n    /* ─── Hero ─────────────────────────────────────────────────── */\n    .hero {\n      position: relative;\n      z-index: 10;\n      min-height: 100vh;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      padding: 120px 40px 80px;\n      text-align: center;\n    }\n\n    .hero-frost {\n      max-width: 820px;\n      width: 100%;\n      padding: 64px 56px;\n      position: relative;\n    }\n\n    .hero-badge {\n      display: inline-flex;\n      align-items: center;\n      gap: 8px;\n      padding: 6px 16px 6px 10px;\n      background: rgba(99,102,241,0.12);\n      border: 1px solid rgba(99,102,241,0.28);\n      border-radius: 100px;\n      font-size: 0.78rem;\n      font-weight: 600;\n      color: #a5b4fc;\n      letter-spacing: 0.03em;\n      text-transform: uppercase;\n      margin-bottom: 32px;\n    }\n\n    .pulse-dot {\n      width: 7px;\n      height: 7px;\n      border-radius: 50%;\n      background: #6366f1;\n      box-shadow: 0 0 0 0 rgba(99,102,241,0.7);\n      animation: pulse-ring 2s cubic-bezier(0.455,0.03,0.515,0.955) infinite;\n      flex-shrink: 0;\n    }\n\n    @keyframes pulse-ring {\n      0%   { box-shadow: 0 0 0 0 rgba(99,102,241,0.7); }\n      70%  { box-shadow: 0 0 0 8px rgba(99,102,241,0); }\n      100% { box-shadow: 0 0 0 0 rgba(99,102,241,0); }\n    }\n\n    .hero-title {\n      font-size: clamp(2.2rem, 5vw, 3.6rem);\n      font-weight: 900;\n      line-height: 1.04;\n      letter-spacing: -0.04em;\n      color: #fff;\n      margin-bottom: 24px;\n    }\n\n    .hero-sub {\n      font-size: clamp(0.95rem, 2.2vw, 1.15rem);\n      color: #8890a4;\n      line-height: 1.7;\n      max-width: 580px;\n      margin: 0 auto 40px;\n      font-weight: 400;\n    }\n\n    .hero-actions {\n      display: flex;\n      gap: 14px;\n      justify-content: center;\n      flex-wrap: wrap;\n    }\n\n    /* ─── Divider ──────────────────────────────────────────────── */\n    .divider {\n      width: 100%;\n      height: 1px;\n      background: linear-gradient(90deg, transparent, rgba(99,102,241,0.3), rgba(139,92,246,0.3), transparent);\n      margin: 0;\n      position: relative;\n      z-index: 10;\n    }\n\n    /* ─── Sections ─────────────────────────────────────────────── */\n    .section {\n      position: relative;\n      z-index: 10;\n      padding: 100px 40px;\n    }\n\n    .section-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n    }\n\n    .section-label {\n      font-size: 0.72rem;\n      font-weight: 700;\n      text-transform: uppercase;\n      letter-spacing: 0.14em;\n      color: #6366f1;\n      margin-bottom: 14px;\n    }\n\n    .section-title {\n      font-size: clamp(2rem, 4.5vw, 3rem);\n      font-weight: 800;\n      color: #fff;\n      letter-spacing: -0.03em;\n      line-height: 1.12;\n      margin-bottom: 18px;\n    }\n\n    .section-desc {\n      font-size: 1rem;\n      color: #7a8194;\n      line-height: 1.7;\n      max-width: 560px;\n    }\n\n    .section-header {\n      margin-bottom: 60px;\n    }\n\n    /* ─── Features Grid ────────────────────────────────────────── */\n    .features-grid {\n      display: grid;\n      grid-template-columns: repeat(2, 1fr);\n      gap: 16px;\n    }\n\n    .feat-card {\n      padding: 28px;\n      background: rgba(255,255,255,0.03);\n      border: 1px solid rgba(255,255,255,0.07);\n      border-radius: 16px;\n      transition: border-color 0.25s, background 0.25s, transform 0.25s;\n      cursor: default;\n    }\n\n    .feat-card:hover {\n      border-color: rgba(99,102,241,0.35);\n      background: rgba(99,102,241,0.06);\n      transform: translateY(-3px);\n    }\n\n    .feat-icon {\n      width: 44px;\n      height: 44px;\n      border-radius: 12px;\n      background: rgba(99,102,241,0.12);\n      border: 1px solid rgba(99,102,241,0.22);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin-bottom: 16px;\n      flex-shrink: 0;\n    }\n\n    .feat-icon svg {\n      width: 20px;\n      height: 20px;\n      color: #818cf8;\n      stroke: #818cf8;\n    }\n\n    .feat-card h3 {\n      font-size: 1rem;\n      font-weight: 700;\n      color: #e2e4ed;\n      margin-bottom: 8px;\n      letter-spacing: -0.01em;\n    }\n\n    .feat-card p {\n      font-size: 0.875rem;\n      color: #6d7588;\n      line-height: 1.65;\n    }\n\n    /* ─── Architecture Diagram ─────────────────────────────────── */\n    .arch-diagram {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      gap: 0;\n      padding: 48px 24px;\n      max-width: 600px;\n      margin: 0 auto;\n    }\n\n    .arch-node-central {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      gap: 6px;\n      padding: 20px 32px;\n      background: linear-gradient(135deg, rgba(99,102,241,0.18) 0%, rgba(139,92,246,0.12) 100%);\n      border: 1px solid rgba(99,102,241,0.35);\n      border-radius: 14px;\n      text-align: center;\n      min-width: 180px;\n    }\n\n    .arch-node-central span {\n      font-size: 0.95rem;\n      font-weight: 700;\n      color: #fff;\n    }\n\n    .arch-node-client {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      gap: 6px;\n      padding: 18px 28px;\n      background: rgba(255,255,255,0.05);\n      border: 1px solid rgba(255,255,255,0.1);\n      border-radius: 14px;\n      text-align: center;\n      min-width: 180px;\n    }\n\n    .arch-node-client span {\n      font-size: 0.9rem;\n      font-weight: 700;\n      color: #e2e4ed;\n    }\n\n    .arch-node-server {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      gap: 6px;\n      padding: 16px 22px;\n      background: rgba(255,255,255,0.04);\n      border: 1px solid rgba(255,255,255,0.08);\n      border-radius: 12px;\n      text-align: center;\n      min-width: 130px;\n    }\n\n    .arch-node-server span {\n      font-size: 0.85rem;\n      font-weight: 600;\n      color: #c8ccd8;\n    }\n\n    .arch-meta {\n      font-size: 0.72rem;\n      color: #5a6170;\n      font-weight: 500;\n    }\n\n    .arch-dot {\n      width: 8px;\n      height: 8px;\n      border-radius: 50%;\n      flex-shrink: 0;\n    }\n\n    .arch-dot-green  { background: #34d399; box-shadow: 0 0 6px rgba(52,211,153,0.5); }\n    .arch-dot-blue   { background: #60a5fa; box-shadow: 0 0 6px rgba(96,165,250,0.5); }\n    .arch-dot-purple { background: #c084fc; box-shadow: 0 0 6px rgba(192,132,252,0.5); }\n\n    .arch-line {\n      width: 1px;\n      height: 36px;\n      background: linear-gradient(to bottom, rgba(99,102,241,0.5), rgba(99,102,241,0.15));\n      margin: 0 auto;\n    }\n\n    .arch-row {\n      display: flex;\n      gap: 20px;\n      justify-content: center;\n      align-items: flex-start;\n    }\n\n    .arch-col {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    /* ─── Tech Pills ───────────────────────────────────────────── */\n    .tech-pills {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 10px;\n      margin-top: 36px;\n    }\n\n    .tech-pill {\n      padding: 7px 16px;\n      background: rgba(255,255,255,0.04);\n      border: 1px solid rgba(255,255,255,0.09);\n      border-radius: 100px;\n      font-size: 0.8rem;\n      font-weight: 600;\n      color: #8890a4;\n      transition: background 0.2s, border-color 0.2s, color 0.2s, transform 0.2s;\n      cursor: default;\n    }\n\n    .tech-pill:hover {\n      background: rgba(99,102,241,0.12);\n      border-color: rgba(99,102,241,0.35);\n      color: #c4b5fd;\n      transform: translateY(-2px);\n    }\n\n    /* ─── Scroll Animations ────────────────────────────────────── */\n    .reveal {\n      opacity: 0;\n      transform: translateY(28px);\n      transition: opacity 0.65s cubic-bezier(0.16,1,0.3,1), transform 0.65s cubic-bezier(0.16,1,0.3,1);\n    }\n\n    .reveal.visible {\n      opacity: 1;\n      transform: none;\n    }\n\n    .stagger { opacity: 0; transform: translateY(20px); }\n\n    .stagger.visible {\n      opacity: 1;\n      transform: none;\n      transition: opacity 0.55s cubic-bezier(0.16,1,0.3,1), transform 0.55s cubic-bezier(0.16,1,0.3,1);\n    }\n\n    /* ─── Footer ───────────────────────────────────────────────── */\n    .footer {\n      position: relative;\n      z-index: 10;\n      border-top: 1px solid rgba(255,255,255,0.06);\n      padding: 40px 40px;\n    }\n\n    .footer-inner {\n      max-width: 1100px;\n      margin: 0 auto;\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      flex-wrap: wrap;\n      gap: 20px;\n    }\n\n    .footer-left {\n      font-size: 0.85rem;\n      color: #4a5068;\n      font-weight: 500;\n    }\n\n    .footer-right {\n      display: flex;\n      gap: 24px;\n    }\n\n    .footer-right a {\n      font-size: 0.85rem;\n      color: #4a5068;\n      text-decoration: none;\n      font-weight: 500;\n      transition: color 0.2s;\n    }\n\n    .footer-right a:hover { color: #a5b4fc; }\n\n    /* ─── Responsive ───────────────────────────────────────────── */\n    @media (max-width: 900px) {\n      .nav-links { display: none; }\n      .nav-hamburger { display: flex; }\n      .hero { padding: 100px 24px 60px; }\n      .hero-frost { padding: 44px 28px; }\n      .section { padding: 72px 24px; }\n      .features-grid { grid-template-columns: 1fr; }\n      .arch-row { flex-direction: column; align-items: center; gap: 0; }\n      .arch-col .arch-line { height: 24px; }\n    }\n\n    @media (max-width: 640px) {\n      .nav { padding: 16px 20px; }\n      .nav.scrolled { padding: 12px 20px; }\n      .hero-frost { padding: 32px 20px; }\n      .hero-actions { flex-direction: column; align-items: center; }\n      .footer { padding: 32px 20px; }\n      .footer-inner { flex-direction: column; align-items: flex-start; gap: 12px; }\n    }\n  </style>\n</head>\n<body>\n\n  <!-- Three.js canvas -->\n  <canvas id=\"hero-canvas\"></canvas>\n  <div class=\"bg-glow\"></div>\n  <div id=\"scroll-darken\"></div>\n\n  <!-- ── Navbar ──────────────────────────────────────────────── -->\n  <nav class=\"nav\" id=\"navbar\">\n    <a href=\"#\" class=\"nav-logo\">owncloud.ai</a>\n\n    <ul class=\"nav-links\">\n      <li><a href=\"#stack\">Stack</a></li>\n      <li><a href=\"#hardware\">Hardware</a></li>\n    </ul>\n\n    <div class=\"nav-right\">\n      <a href=\"https://github.com/xunholy/k8s-gitops\" target=\"_blank\" rel=\"noopener\" class=\"nav-gh\">\n        <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n          <path d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"/>\n        </svg>\n        GitHub\n      </a><a href=\"https://github.com/xunholy/k8s-gitops/stargazers\" target=\"_blank\" rel=\"noopener\" class=\"nav-stars\" id=\"star-count\">\n        <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n          <path d=\"M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279L12 19.771l-7.416 3.642 1.48-8.279L0 9.306l8.332-1.151z\"/>\n        </svg>\n        <span>--</span>\n      </a>\n    </div>\n\n    <button class=\"nav-hamburger\" id=\"hamburger\" aria-label=\"Toggle menu\">\n      <span></span><span></span><span></span>\n    </button>\n  </nav>\n\n  <!-- Mobile menu -->\n  <div class=\"nav-mobile\" id=\"mobile-menu\">\n    <a href=\"#stack\" onclick=\"closeMobile()\">Stack</a>\n    <a href=\"#hardware\" onclick=\"closeMobile()\">Hardware</a>\n    <a href=\"https://github.com/xunholy/k8s-gitops\" target=\"_blank\" rel=\"noopener\">GitHub</a>\n  </div>\n\n  <!-- ── Hero ─────────────────────────────────────────────────── -->\n  <section class=\"hero\">\n    <div class=\"frost hero-frost\">\n      <h1 class=\"hero-title\">\n        My <span class=\"accent\">Own</span><br>Cloud\n      </h1>\n      <div class=\"hero-actions\">\n        <a href=\"https://github.com/xunholy/k8s-gitops\" target=\"_blank\" rel=\"noopener\" class=\"btn-primary btn-wave\">\n          <!-- Lightning bolt -->\n          <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n            <polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"/>\n          </svg>\n          View on GitHub\n        </a>\n        <a href=\"#stack\" class=\"btn-ghost\">\n          <!-- Down arrow -->\n          <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n            <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><polyline points=\"19 12 12 19 5 12\"/>\n          </svg>\n          Explore Stack\n        </a>\n      </div>\n    </div>\n  </section>\n\n  <div class=\"divider\"></div>\n\n  <!-- ── Stack Section ─────────────────────────────────────────── -->\n  <section class=\"section\" id=\"stack\">\n    <div class=\"section-inner\">\n      <div class=\"frost\" style=\"padding: 56px 48px;\">\n        <div class=\"section-header reveal\">\n          <div class=\"section-label\">Technology Stack</div>\n          <h2 class=\"section-title\">What's running</h2>\n          <p class=\"section-desc\">A homelab built on Talos Linux, FluxCD, and the CNCF ecosystem. GitOps, observability, and security — all from home.</p>\n        </div>\n        <div class=\"features-grid\">\n\n          <!-- Talos Linux -->\n          <div class=\"feat-card stagger\">\n            <div class=\"feat-icon\">\n              <!-- Server icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <rect x=\"2\" y=\"2\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"/>\n                <rect x=\"2\" y=\"14\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"/>\n                <line x1=\"6\" y1=\"6\" x2=\"6.01\" y2=\"6\"/>\n                <line x1=\"6\" y1=\"18\" x2=\"6.01\" y2=\"18\"/>\n              </svg>\n            </div>\n            <h3>Talos Linux</h3>\n            <p>Minimal, immutable Kubernetes OS with API-driven management. No SSH, no shell — just Kubernetes.</p>\n          </div>\n\n          <!-- FluxCD -->\n          <div class=\"feat-card stagger\">\n            <div class=\"feat-icon\">\n              <!-- Refresh/cycle icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <polyline points=\"1 4 1 10 7 10\"/>\n                <polyline points=\"23 20 23 14 17 14\"/>\n                <path d=\"M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15\"/>\n              </svg>\n            </div>\n            <h3>FluxCD GitOps</h3>\n            <p>Declarative cluster management with Flux Operator. Every change goes through Git — review, approve, deploy.</p>\n          </div>\n\n          <!-- Cilium -->\n          <div class=\"feat-card stagger\">\n            <div class=\"feat-icon\">\n              <!-- Shield icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\n              </svg>\n            </div>\n            <h3>Cilium CNI</h3>\n            <p>eBPF-powered networking with transparent encryption, network policies, and Hubble observability built in.</p>\n          </div>\n\n          <!-- Rook-Ceph -->\n          <div class=\"feat-card stagger\">\n            <div class=\"feat-icon\">\n              <!-- Database icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"/>\n                <path d=\"M21 12c0 1.66-4 3-9 3s-9-1.34-9-3\"/>\n                <path d=\"M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5\"/>\n              </svg>\n            </div>\n            <h3>Rook-Ceph Storage</h3>\n            <p>Distributed block and object storage with replication, snapshots, and VolSync backup integration.</p>\n          </div>\n\n          <!-- Observability -->\n          <div class=\"feat-card stagger\">\n            <div class=\"feat-icon\">\n              <!-- Activity/chart icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <polyline points=\"22 12 18 12 15 21 9 3 6 12 2 12\"/>\n              </svg>\n            </div>\n            <h3>Full Observability</h3>\n            <p>Prometheus, Grafana, Loki, and Alertmanager for metrics, logs, dashboards, and alerting.</p>\n          </div>\n\n          <!-- Zero-Trust Security -->\n          <div class=\"feat-card stagger\">\n            <div class=\"feat-icon\">\n              <!-- Lock icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"/>\n                <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/>\n              </svg>\n            </div>\n            <h3>Zero-Trust Security</h3>\n            <p>SOPS-encrypted secrets, Dex SSO with GitHub OAuth, cert-manager TLS, and Envoy Gateway.</p>\n          </div>\n\n        </div>\n      </div>\n    </div>\n  </section>\n\n  <div class=\"divider\"></div>\n\n  <!-- ── Hardware Section ──────────────────────────────────────── -->\n  <section class=\"section\" id=\"hardware\">\n    <div class=\"section-inner\">\n      <div class=\"frost\" style=\"padding: 56px 48px;\">\n        <div class=\"section-header reveal\">\n          <div class=\"section-label\">Hardware</div>\n          <h2 class=\"section-title\">The Rack</h2>\n          <p class=\"section-desc\">Purpose-built for reliability and performance.</p>\n        </div>\n\n        <div class=\"features-grid\">\n\n          <!-- Asus NUC -->\n          <div class=\"feat-card reveal\">\n            <div class=\"feat-icon\">\n              <!-- CPU icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\"/>\n                <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\"/>\n                <line x1=\"9\" y1=\"1\" x2=\"9\" y2=\"4\"/>\n                <line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"4\"/>\n                <line x1=\"9\" y1=\"20\" x2=\"9\" y2=\"23\"/>\n                <line x1=\"15\" y1=\"20\" x2=\"15\" y2=\"23\"/>\n                <line x1=\"20\" y1=\"9\" x2=\"23\" y2=\"9\"/>\n                <line x1=\"20\" y1=\"14\" x2=\"23\" y2=\"14\"/>\n                <line x1=\"1\" y1=\"9\" x2=\"4\" y2=\"9\"/>\n                <line x1=\"1\" y1=\"14\" x2=\"4\" y2=\"14\"/>\n              </svg>\n            </div>\n            <h3>Asus NUC 14 Pro</h3>\n            <p>3x Control Plane · 14 cores · 48GB RAM · 2TB storage</p>\n          </div>\n\n          <!-- Ubiquiti -->\n          <div class=\"feat-card reveal\">\n            <div class=\"feat-icon\">\n              <!-- Wifi/router icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <path d=\"M5 12.55a11 11 0 0 1 14.08 0\"/>\n                <path d=\"M1.42 9a16 16 0 0 1 21.16 0\"/>\n                <path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\"/>\n                <line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\"/>\n              </svg>\n            </div>\n            <h3>Ubiquiti UDM-Pro-Max</h3>\n            <p>Router &amp; Gateway · 8TB storage · UniFi OS</p>\n          </div>\n\n          <!-- TrueNAS -->\n          <div class=\"feat-card reveal\">\n            <div class=\"feat-icon\">\n              <!-- Hard drive icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <line x1=\"22\" y1=\"12\" x2=\"2\" y2=\"12\"/>\n                <path d=\"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\"/>\n                <line x1=\"6\" y1=\"16\" x2=\"6.01\" y2=\"16\"/>\n                <line x1=\"10\" y1=\"16\" x2=\"10.01\" y2=\"16\"/>\n              </svg>\n            </div>\n            <h3>TrueNAS</h3>\n            <p>Network attached storage · 48TB · Backup target</p>\n          </div>\n\n          <!-- JetKVM -->\n          <div class=\"feat-card reveal\">\n            <div class=\"feat-icon\">\n              <!-- Monitor icon -->\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n                <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"/>\n                <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"/>\n                <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"/>\n              </svg>\n            </div>\n            <h3>JetKVM</h3>\n            <p>3x Remote KVM · Out-of-band management</p>\n          </div>\n\n        </div>\n      </div>\n    </div>\n  </section>\n\n  <div class=\"divider\"></div>\n\n  <!-- ── Ecosystem Section ─────────────────────────────────────── -->\n  <section class=\"section\" id=\"ecosystem\">\n    <div class=\"section-inner\">\n      <div class=\"frost\" style=\"padding: 56px 48px;\">\n        <div class=\"section-header reveal\">\n          <div class=\"section-label\">Ecosystem</div>\n          <h2 class=\"section-title\">Powered by Open Source</h2>\n        </div>\n        <div class=\"tech-pills\">\n          <span class=\"tech-pill stagger\">Talos Linux</span>\n          <span class=\"tech-pill stagger\">FluxCD</span>\n          <span class=\"tech-pill stagger\">Cilium</span>\n          <span class=\"tech-pill stagger\">Envoy Gateway</span>\n          <span class=\"tech-pill stagger\">Rook-Ceph</span>\n          <span class=\"tech-pill stagger\">Prometheus</span>\n          <span class=\"tech-pill stagger\">Grafana</span>\n          <span class=\"tech-pill stagger\">Loki</span>\n          <span class=\"tech-pill stagger\">cert-manager</span>\n          <span class=\"tech-pill stagger\">External Secrets</span>\n          <span class=\"tech-pill stagger\">ExternalDNS</span>\n          <span class=\"tech-pill stagger\">Dex</span>\n          <span class=\"tech-pill stagger\">Spegel</span>\n          <span class=\"tech-pill stagger\">VolSync</span>\n          <span class=\"tech-pill stagger\">Kopia</span>\n          <span class=\"tech-pill stagger\">Renovate</span>\n        </div>\n      </div>\n    </div>\n  </section>\n\n  <!-- ── Footer ───────────────────────────────────────────────── -->\n  <footer class=\"footer\">\n    <div class=\"footer-inner\">\n      <div class=\"footer-left\">© 2026 owncloud.ai</div>\n      <div class=\"footer-right\">\n        <a href=\"https://github.com/xunholy/k8s-gitops\" target=\"_blank\" rel=\"noopener\">GitHub</a>\n        <a href=\"https://discord.gg/home-operations\" target=\"_blank\" rel=\"noopener\">Discord</a>\n      </div>\n    </div>\n  </footer>\n\n  <!-- ── Scripts ──────────────────────────────────────────────── -->\n\n  <!-- Three.js from CDN -->\n  <script src=\"https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js\"></script>\n\n  <script>\n    /* ── Navbar scroll handler ──────────────────────────── */\n    const navbar = document.getElementById('navbar');\n    const darken = document.getElementById('scroll-darken');\n\n    function onScroll() {\n      const y  = window.scrollY;\n      const vh = window.innerHeight;\n\n      // Scrolled class\n      navbar.classList.toggle('scrolled', y > 30);\n\n      // Darken overlay (max 0.75 opacity)\n      const darkenProgress = Math.min(y / (vh * 2), 0.75);\n      darken.style.opacity = darkenProgress;\n    }\n\n    window.addEventListener('scroll', onScroll, { passive: true });\n\n    /* ── Mobile menu toggle ─────────────────────────────── */\n    const hamburger  = document.getElementById('hamburger');\n    const mobileMenu = document.getElementById('mobile-menu');\n\n    hamburger.addEventListener('click', () => {\n      const open = mobileMenu.classList.toggle('open');\n      hamburger.classList.toggle('open', open);\n      hamburger.setAttribute('aria-expanded', open);\n    });\n\n    function closeMobile() {\n      mobileMenu.classList.remove('open');\n      hamburger.classList.remove('open');\n      hamburger.setAttribute('aria-expanded', false);\n    }\n\n    /* ── GitHub star count ─────────────────────────────────── */\n    fetch('https://api.github.com/repos/xunholy/k8s-gitops')\n      .then(r => r.json())\n      .then(data => {\n        if (data.stargazers_count != null) {\n          document.querySelector('#star-count span').textContent = data.stargazers_count.toLocaleString();\n        }\n      })\n      .catch(() => {});\n\n    /* ── IntersectionObserver — reveal & stagger ────────── */\n    const revealEls = document.querySelectorAll('.reveal');\n    const staggerEls = document.querySelectorAll('.stagger');\n\n    const revealObserver = new IntersectionObserver((entries) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          entry.target.classList.add('visible');\n          revealObserver.unobserve(entry.target);\n        }\n      });\n    }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });\n\n    revealEls.forEach(el => revealObserver.observe(el));\n\n    const staggerObserver = new IntersectionObserver((entries) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          const siblings = Array.from(\n            entry.target.closest('.features-grid, .tech-pills, .frost')\n              ?.querySelectorAll('.stagger') || [entry.target]\n          );\n          const idx = siblings.indexOf(entry.target);\n          setTimeout(() => {\n            entry.target.classList.add('visible');\n          }, idx * 70);\n          staggerObserver.unobserve(entry.target);\n        }\n      });\n    }, { threshold: 0.05, rootMargin: '0px 0px -20px 0px' });\n\n    staggerEls.forEach(el => staggerObserver.observe(el));\n\n    /* ── Three.js animated wireframe orb (ecto.chat style) ── */\n    (function() {\n      if (typeof THREE === 'undefined') return;\n\n      const canvas   = document.getElementById('hero-canvas');\n      const renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true });\n      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n\n      const scene  = new THREE.Scene();\n      const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);\n      camera.position.z = 5;\n\n      // Outer wireframe sphere\n      const geo     = new THREE.IcosahedronGeometry(1.8, 24);\n      const origPos = new Float32Array(geo.attributes.position.array);\n\n      const wireMat = new THREE.MeshBasicMaterial({\n        color: 0x7c3aed,\n        wireframe: true,\n        transparent: true,\n        opacity: 0.12,\n      });\n      const wire = new THREE.Mesh(geo, wireMat);\n      scene.add(wire);\n\n      // Inner emissive sphere\n      const innerGeo = new THREE.IcosahedronGeometry(1.75, 16);\n      const innerMat = new THREE.MeshStandardMaterial({\n        color: 0x0a0a1a,\n        emissive: 0x2e1065,\n        emissiveIntensity: 0.4,\n        metalness: 0.9,\n        roughness: 0.7,\n        transparent: true,\n        opacity: 0.6,\n      });\n      const inner = new THREE.Mesh(innerGeo, innerMat);\n      scene.add(inner);\n\n      // Lights\n      const light1 = new THREE.PointLight(0x7c3aed, 2, 12);\n      light1.position.set(3, 2, 4);\n      scene.add(light1);\n      const light2 = new THREE.PointLight(0x6366f1, 1.5, 12);\n      light2.position.set(-3, -2, 3);\n      scene.add(light2);\n      scene.add(new THREE.AmbientLight(0x1a1a2e, 0.5));\n\n      // Vertex displacement\n      function displace(time) {\n        const pos = geo.attributes.position.array;\n        for (let i = 0; i < pos.length; i += 3) {\n          const ox = origPos[i], oy = origPos[i+1], oz = origPos[i+2];\n          const d = Math.sin(ox*2.1+time*0.6)*Math.cos(oy*1.8+time*0.5)*Math.sin(oz*2.4+time*0.7)*0.08\n                  + Math.sin(ox*4.3+oy*3.7+time*0.4)*0.03;\n          const s = 1 + d;\n          pos[i] = ox*s; pos[i+1] = oy*s; pos[i+2] = oz*s;\n        }\n        geo.attributes.position.needsUpdate = true;\n      }\n\n      // Resize\n      function resize() {\n        const w = window.innerWidth, h = window.innerHeight;\n        renderer.setSize(w, h, false);\n        camera.aspect = w / h;\n        camera.updateProjectionMatrix();\n      }\n\n      wire.position.y  = -0.5;\n      inner.position.y = -0.5;\n\n      window.addEventListener('resize', resize);\n      resize();\n\n      // Mouse parallax\n      let mx = 0, my = 0;\n      window.addEventListener('mousemove', (e) => {\n        mx = (e.clientX / window.innerWidth  - 0.5) * 0.3;\n        my = (e.clientY / window.innerHeight - 0.5) * 0.3;\n      }, { passive: true });\n\n      let t = 0;\n      function animate() {\n        requestAnimationFrame(animate);\n        t += 0.008;\n        displace(t * 3);\n        wire.rotation.y  += 0.0015;\n        wire.rotation.x  += 0.0008;\n        inner.rotation.y  = wire.rotation.y;\n        inner.rotation.x  = wire.rotation.x;\n        camera.position.x += (mx - camera.position.x) * 0.02;\n        camera.position.y += (-my - camera.position.y + 0.3) * 0.02;\n        camera.lookAt(0, wire.position.y * 0.5, 0);\n        renderer.render(scene, camera);\n      }\n      animate();\n    })();\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "hack/cf-terraforming.sh",
    "content": "#!/bin/bash\n\n# Note: Requires setting the environment varibale CLOUDFLARE_API_TOKEN with the appropriate cloudflare scoped permissions\n\n# List of Terraform resources to iterate through\n# https://registry.terraform.io/providers/cloudflare/cloudflare/4.0.0/docs\nRESOURCE_LIST=\"cloudflare_access_application\ncloudflare_access_group\ncloudflare_access_mutual_tls_certificate\ncloudflare_access_service_token\ncloudflare_api_shield\ncloudflare_argo\ncloudflare_byo_ip_prefix\ncloudflare_certificate_pack\ncloudflare_custom_hostname\ncloudflare_custom_hostname_fallback_origin\ncloudflare_custom_pages\ncloudflare_custom_ssl\ncloudflare_filter\ncloudflare_firewall_rule\ncloudflare_load_balancer\ncloudflare_load_balancer_monitor\ncloudflare_load_balancer_pool\ncloudflare_logpush_job\ncloudflare_managed_headers\ncloudflare_origin_ca_certificate\ncloudflare_page_rule\ncloudflare_rate_limit\ncloudflare_record\ncloudflare_ruleset\ncloudflare_spectrum_application\ncloudflare_tunnel\ncloudflare_url_normalization_settings\ncloudflare_waiting_room\ncloudflare_worker_route\ncloudflare_workers_kv_namespace\ncloudflare_zone\ncloudflare_zone_settings_override\"\n\n# Iterate through the list of IPs and run the command\nfor RESOURCE in $RESOURCE_LIST; do\n  echo \"Running command on resource: $RESOURCE\"\n  cf-terraforming import --resource-type=$RESOURCE --zone=$CLOUDFLARE_ZONE_ID\ndone\n"
  },
  {
    "path": "hack/delete-all.sh",
    "content": "#!/bin/bash\n\n# Set the target namespace\nNAMESPACE=\"flux-system\"\n\n# # Get all resource types in the namespace and delete them\nRESOURCES=$(kubectl api-resources --verbs=list --namespaced -o name)\n# echo $RESOURCES | xargs -n1 -P10 kubectl delete --all --namespace=$NAMESPACE --ignore-not-found=true\n\n# For each resource type, wait for all resources to be deleted, and then remove finalizers\nfor RESOURCE in $RESOURCES; do\n  # Wait for all resources of this type to be deleted\n  while [[ $(kubectl get $RESOURCE --namespace=$NAMESPACE | wc -l) -gt 1 ]]\n  do\n    echo \"Waiting for $RESOURCE resources to be deleted...\"\n    sleep 1\n  done\n\n  # Remove finalizers from all resources of this type\n  kubectl get $RESOURCE --namespace=$NAMESPACE -o name | xargs -I{} kubectl patch {} --type json -p='[{\"op\": \"remove\", \"path\": \"/metadata/finalizers\"}]'\ndone\n"
  },
  {
    "path": "hack/finalizer-pods.sh",
    "content": "#!/bin/bash\n\n# Get all namespaces in the cluster\nNAMESPACES=$(kubectl get namespaces -o name)\n\n# Loop over each namespace and force update the finalizer for all Pods\nfor NAMESPACE_WITH_PREFIX in $NAMESPACES; do\n  # Remove the prefix \"namespace/\" from the namespace name\n  NAMESPACE=${NAMESPACE_WITH_PREFIX#namespace/}\n  echo \"Updating Pods in namespace $NAMESPACE\"\n  # Get all Pods in the namespace\n  POD_NAMES=$(kubectl get pods -n $NAMESPACE -o name)\n  # Update the finalizer for each Pod in parallel using xargs\n  echo \"$POD_NAMES\" | xargs -n1 -P4 -I{} kubectl patch {} -n $NAMESPACE -p '{\"metadata\":{\"finalizers\":null}}' --type=merge\ndone\n"
  },
  {
    "path": "hack/finalizer.sh",
    "content": "#!/bin/bash\n\n# Set the target namespace\nNAMESPACE=\"flux-system\"\n\n# Get all resource types in the cluster\nRESOURCES=$(kubectl api-resources --verbs=list --namespaced=false -o name)\n\n# Loop over each resource type and force update the finalizer for all resources of that type\nfor RESOURCE in $RESOURCES; do\n  # Get all resources of this type in the target namespace\n  RESOURCE_NAMES=$(kubectl get $RESOURCE -A -o name)\n  # Loop over each resource name and force update the finalizer\n  for RESOURCE_NAME in $RESOURCE_NAMES; do\n    # Update the finalizer for each resource in parallel using xargs\n    echo \"$RESOURCE_NAME\" | xargs -n1 -P4 -I{} kubectl patch {} --namespace=$NAMESPACE -p '{\"metadata\":{\"finalizers\":null}}' --type=merge\n  done\ndone\n"
  },
  {
    "path": "hack/openebs.sh",
    "content": "#!/bin/bash\n\nkubectl get bdc -A --no-headers | awk '{print $2}' | xargs -I {} kubectl patch -n openebs bdc {} -p '{\"metadata\":{\"finalizers\":null}}' --type=merge\n"
  },
  {
    "path": "hack/restart.sh",
    "content": "#!/bin/bash\n\n# List of IPs to iterate through\nIP_LIST=\"192.168.50.111 192.168.50.112 192.168.50.113\"\n\n# Iterate through the list of IPs and run the command\nfor IP in $IP_LIST; do\n  echo \"Running command on $IP\"\n  talosctl reboot -n $IP -e 192.168.50.111\ndone\n"
  },
  {
    "path": "hack/update.sh",
    "content": "#!/bin/bash\nset -e\nset -u\nset -o pipefail\n\n# This script upgrades Talos on a list of specified IP addresses.\n# Instructions https://www.talos.dev/v1.4/talos-guides/upgrading-talos/\n# Note: Use the version of the documentation corrosponding with the upgrade path.\n\n# List of IPs to process\nreadonly IP_LIST=(\n  # \"192.168.50.111\"\n  # \"192.168.50.112\"\n  # \"192.168.50.113\"\n  # \"192.168.50.114\"\n  # \"192.168.50.115\"\n  # \"192.168.50.116\"\n  \"192.168.50.121\"\n  \"192.168.50.122\"\n  \"192.168.50.123\"\n  \"192.168.50.124\"\n)\n\n# Define the Talos installer image\nreadonly INSTALLER_IMAGE=\"ghcr.io/siderolabs/installer:v1.4.0\"\n\n# Upgrade Talos on each IP address\nfor IP in \"${IP_LIST[@]}\"; do\n  echo \"Upgrading Talos on $IP\"\n  talosctl upgrade -n \"$IP\" -e \"$IP\" \\\n    --image \"$INSTALLER_IMAGE\" \\\n    --wait --preserve\ndone\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: github-app-secret\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: github-app-secret\n    template:\n      data:\n        github_app_id: '{{ .ACTIONS_RUNNER_APP_ID }}'\n        github_app_installation_id: '{{ .ACTIONS_RUNNER_INSTALLATION_ID }}'\n        github_app_private_key: '{{ .ACTIONS_RUNNER_PRIVATE_KEY }}'\n  dataFrom:\n    - extract:\n        key: actions-runner\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app gha-runner-scale-set\n  namespace: actions-runner-system\nspec:\n  interval: 15m\n  chartRef:\n    kind: OCIRepository\n    name: gha-runner-scale-set\n  dependsOn:\n    - name: gha-runner-scale-set-controller\n      namespace: actions-runner-system\n  values:\n    nameOverride: gha-runner-scale-set\n    runnerScaleSetName: gha-runner-scale-set\n    githubConfigSecret: github-app-secret\n    githubConfigUrl: https://github.com/xunholy/k8s-gitops\n    maxRunners: 3\n    minRunners: 1\n    controllerServiceAccount:\n      name: gha-runner-scale-set-controller\n      namespace: actions-runner-system\n    containerMode:\n      type: kubernetes\n      kubernetesModeWorkVolumeClaim:\n        accessModes: [\"ReadWriteOnce\"]\n        storageClassName: truenas-iscsi-csi\n        resources:\n          requests:\n            storage: 1Gi\n    template:\n      spec:\n        securityContext:\n          fsGroup: 123\n        containers:\n          - name: runner\n            image: ghcr.io/home-operations/actions-runner:2.334.0@sha256:95d91d7f8d241e319ef2f4fec08f417aa1606b96fbb327643f75c303acd30002\n            command: [\"/home/runner/run.sh\"]\n            env:\n              - name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER\n                value: \"false\"\n              - name: NODE\n                valueFrom:\n                  fieldRef:\n                    fieldPath: status.hostIP\n            volumeMounts:\n              - mountPath: /var/run/secrets/talos.dev\n                name: talos\n                readOnly: true\n        serviceAccountName: k8s-gitops-runner\n        volumes:\n          - name: talos\n            secret:\n              secretName: k8s-gitops-runner\n    listenerMetrics:\n      counters:\n        gha_started_jobs_total:\n          labels: [\"repository\", \"organization\", \"enterprise\", \"job_name\", \"event_name\"]\n        gha_completed_jobs_total:\n          labels: [\"repository\", \"organization\", \"enterprise\", \"job_name\", \"event_name\", \"job_result\"]\n      gauges:\n        gha_assigned_jobs:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n        gha_running_jobs:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n        gha_registered_runners:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n        gha_busy_runners:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n        gha_min_runners:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n        gha_max_runners:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n        gha_desired_runners:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n        gha_idle_runners:\n          labels: [\"name\", \"namespace\", \"repository\", \"organization\", \"enterprise\"]\n      histograms:\n        gha_job_startup_duration_seconds:\n          labels: [\"repository\", \"organization\", \"enterprise\", \"job_name\", \"event_name\"]\n          buckets: [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 15.0, 18.0, 20.0, 25.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0, 120.0, 150.0, 180.0, 210.0, 240.0, 300.0, 360.0, 420.0, 480.0, 540.0, 600.0, 900.0, 1200.0, 1800.0, 2400.0, 3000.0, 3600.0]\n        gha_job_execution_duration_seconds:\n          labels: [\"repository\", \"organization\", \"enterprise\", \"job_name\", \"event_name\", \"job_result\"]\n          buckets: [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 15.0, 18.0, 20.0, 25.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0, 120.0, 150.0, 180.0, 210.0, 240.0, 300.0, 360.0, 420.0, 480.0, 540.0, 600.0, 900.0, 1200.0, 1800.0, 2400.0, 3000.0, 3600.0]\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - rbac.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: gha-runner-scale-set\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.14.1\n  url: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set/app/rbac.yaml",
    "content": "---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: k8s-gitops-runner\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: k8s-gitops-runner\nrules:\n  # Flux resources - full management\n  - apiGroups: [\"kustomize.toolkit.fluxcd.io\"]\n    resources: [\"*\"]\n    verbs: [\"*\"]\n  - apiGroups: [\"helm.toolkit.fluxcd.io\"]\n    resources: [\"*\"]\n    verbs: [\"*\"]\n  - apiGroups: [\"source.toolkit.fluxcd.io\"]\n    resources: [\"*\"]\n    verbs: [\"*\"]\n  - apiGroups: [\"notification.toolkit.fluxcd.io\"]\n    resources: [\"*\"]\n    verbs: [\"*\"]\n  # Core resources - read + create/patch\n  - apiGroups: [\"\"]\n    resources: [\"namespaces\", \"configmaps\", \"secrets\", \"serviceaccounts\"]\n    verbs: [\"get\", \"list\", \"watch\", \"create\", \"update\", \"patch\"]\n  - apiGroups: [\"\"]\n    resources: [\"pods\", \"services\", \"endpoints\", \"events\", \"nodes\"]\n    verbs: [\"get\", \"list\", \"watch\"]\n  # Workload resources - read\n  - apiGroups: [\"apps\"]\n    resources: [\"deployments\", \"statefulsets\", \"daemonsets\", \"replicasets\"]\n    verbs: [\"get\", \"list\", \"watch\"]\n  # RBAC - read\n  - apiGroups: [\"rbac.authorization.k8s.io\"]\n    resources: [\"clusterroles\", \"clusterrolebindings\", \"roles\", \"rolebindings\"]\n    verbs: [\"get\", \"list\", \"watch\"]\n  # CRDs - read\n  - apiGroups: [\"apiextensions.k8s.io\"]\n    resources: [\"customresourcedefinitions\"]\n    verbs: [\"get\", \"list\", \"watch\"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: k8s-gitops-runner\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: k8s-gitops-runner\nsubjects:\n  - kind: ServiceAccount\n    name: k8s-gitops-runner\n    namespace: actions-runner-system\n---\napiVersion: talos.dev/v1alpha1\nkind: ServiceAccount\nmetadata:\n  name: k8s-gitops-runner\nspec:\n  roles: [\"os:admin\"]\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: actions-runner-scale-set\n  namespace: actions-runner-system\nspec:\n  dependsOn:\n    - name: gha-runner-scale-set-controller\n      namespace: actions-runner-system\n    - name: onepassword\n      namespace: external-secrets\n  path: \"./apps/base/actions-runner-system/gha-runner-scale-set/app\"\n  wait: true\n  targetNamespace: actions-runner-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: actions-runner-scale-set\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set-controller/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app gha-runner-scale-set-controller\nspec:\n  interval: 15m\n  chartRef:\n    kind: OCIRepository\n    name: gha-runner-scale-set-controller\n  values:\n    fullnameOverride: gha-runner-scale-set-controller\n    replicaCount: 1\n    priorityClassName: platform-cluster-critical\n    metrics:\n      controllerManagerAddr: \":8080\"\n      listenerAddr: \":8080\"\n      listenerEndpoint: \"/metrics\"\n    flags:\n      logLevel: \"debug\"\n      logFormat: \"json\"\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set-controller/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set-controller/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: gha-runner-scale-set-controller\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.14.1\n  url: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/gha-runner-scale-set-controller/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: gha-runner-scale-set-controller\n  namespace: actions-runner-system\nspec:\n  path: \"./apps/base/actions-runner-system/gha-runner-scale-set-controller/app\"\n  wait: true\n  targetNamespace: actions-runner-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: gha-runner-scale-set-controller\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: actions-runner-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/actions-runner-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: actions-runner-system\n  labels:\n    pod-security.kubernetes.io/warn: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    kustomize.toolkit.fluxcd.io/prune: disabled\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kagent\n  namespace: ai-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kagent\n  valuesFrom:\n    - kind: ConfigMap\n      name: kagent-values\n    - kind: Secret\n      name: kagent-values-secret\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: kagent-values\n    files:\n      - values.yaml=./values.yaml\n\nsecretGenerator:\n  - name: kagent-values-secret\n    namespace: ai-system\n    files:\n      - values.yaml=values.enc.age.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n  - kind: Secret\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kagent\n  namespace: ai-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.9.4\n  url: oci://ghcr.io/kagent-dev/kagent/helm/kagent\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/app/values.enc.age.yaml",
    "content": "providers:\n  openAI:\n    apiKey: PLACEHOLDER\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDRXpYSDI2ZWFGQ2ZaOVVV\n        NitUM290S2xIWDYwR3F4UTUyNkUzNkxKMmlBCmw3TEo2ZlI2Smt2RWVUK3lBMXVR\n        UDhpanJhTU16a1RsT2p1RkdSczQ4UlUKLS0tIGEyVTBrTjJ5R3RIclEyUm1DbzQy\n        WURjVy9QV0VadG5lZERmbzFKQ09oNjQKJBrP1aC9RFZropDxKb0Mm7Gmm7SMJYTI\n        9CKg+E8kB8+5F/BnVNCBqsbXqOXCEDMGD7rbtulR/UdwMzaIhx6ZrQ==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:21:04Z\"\n  mac: ENC[AES256_GCM,data:zfFjgC62XPfpQ+1QQY7/0L7D/2xudrc/tadEyHxngjQojMX8UyGljnwh9rJrDHqDnL0XYlN+Y52QgraqfC0yrAKUvEBL162RUv48b2WUY/gzc9xkUc0VqaDQ/9rmDFttG6D4TPsoqNLHHISGP7ZCSYFoK0jYRfPhBDwXDDUhUqA=,iv:EZAFHGTbvXbcktWRCW+XWjXtQB/ZibdCWnnyDT0DnMU=,tag:TKMiYIkxcvhw4GycP1FxvQ==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/app/values.yaml",
    "content": "---\nproviders:\n  default: openAI\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/crds/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kagent-crds\n  namespace: ai-system\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kagent-crds\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: warn\n  maxHistory: 3\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/crds/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/crds/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kagent-crds\n  namespace: ai-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.9.4\n  url: oci://ghcr.io/kagent-dev/kagent/helm/kagent-crds\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kagent/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kagent\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/kagent/app\"\n  wait: false\n  dependsOn:\n    - name: kagent-crds\n      namespace: ai-system\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kagent\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kagent-crds\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/kagent/crds\"\n  wait: false\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kagent-crds\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kgateway\n  namespace: ai-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kgateway\n  valuesFrom:\n    - kind: ConfigMap\n      name: kgateway-values\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: kgateway-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kgateway\n  namespace: ai-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 2.3.0\n  url: oci://ghcr.io/kgateway-dev/charts/kgateway\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/app/values.yaml",
    "content": "---\ncontroller:\n  image:\n    tag: \"v2.1.1\"\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/crds/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kgateway-crds\n  namespace: ai-system\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kgateway-crds\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: warn\n  maxHistory: 3\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/crds/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/crds/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kgateway-crds\n  namespace: ai-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 2.3.0\n  url: oci://ghcr.io/kgateway-dev/charts/kgateway-crds\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kgateway/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kgateway\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/kgateway/app\"\n  wait: false\n  dependsOn:\n    - name: kgateway-crds\n      namespace: ai-system\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kgateway\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kgateway-crds\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/kgateway/crds\"\n  wait: false\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kgateway-crds\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kmcp\n  namespace: ai-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kmcp\n  valuesFrom:\n    - kind: ConfigMap\n      name: kmcp-values\n    - kind: Secret\n      name: kmcp-values-secret\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: kmcp-values\n    files:\n      - values.yaml=./values.yaml\n\nsecretGenerator:\n  - name: kmcp-values-secret\n    namespace: ai-system\n    files:\n      - values.yaml=values.enc.age.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n  - kind: Secret\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kmcp\n  namespace: ai-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.3.0\n  url: oci://ghcr.io/kagent-dev/kmcp/helm/kmcp\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/app/values.enc.age.yaml",
    "content": "providers:\n  openAI:\n    apiKey: PLACEHOLDER\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCelZ0dmJpdFA0N1E3ZlJm\n        clF2QS92WkQxSkN1N2EvUDRyUXhrK2ZnbXhRClY5cUZDUWtmTE5jYXFUWmhXV1NV\n        Y3FlS3VqUUYwQVIxVFJnMGFZY0kxRU0KLS0tIFplanpSaTBVYmNsa3pvTndETmo1\n        ZjN1b3B5amQ1a1p0aUd3ekVwbWFJYmMKP8fsQVE/tw+FHz0keS3RRTj0sPituzPb\n        ws3GC9k6yeHO5RHj+XubNp/M44bFG6o0Zf1hn+D3ux1M8LvGguE/Gw==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:21:04Z\"\n  mac: ENC[AES256_GCM,data:6f/Yc+wg2oCFY6lSfWPfL107/TmDA4NpDjjIhxQlpNt/R3xPRWjuc94dX99syhbg0MXU8oGwGdA1LVv8AIwRkPH31n92Qh+c4f0oMcxGk6ShTL4H1PHCwVuYMNy9q+6AKGuC9T/XFluQo32d03JgUgvJR+RuDH6ZBsv3JWbTeQc=,iv:5jiYBzRoAclR/kjXhKuW83AqLNWJfDFGZzpDXBvU2ys=,tag:08GAUl50lJ3+dLEHhNBlFg==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/app/values.yaml",
    "content": "---\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/crds/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kmcp-crds\n  namespace: ai-system\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kmcp-crds\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: warn\n  maxHistory: 3\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/crds/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/crds/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kmcp-crds\n  namespace: ai-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.3.0\n  url: oci://ghcr.io/kagent-dev/kmcp/helm/kmcp-crds\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kmcp/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kmcp\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/kmcp/app\"\n  wait: false\n  dependsOn:\n    - name: kmcp-crds\n      namespace: ai-system\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kmcp\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kmcp-crds\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/kmcp/crds\"\n  wait: false\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kmcp-crds\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n  # - networkpolicy.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app n8n\nspec:\n  interval: 1h\n  chart:\n    spec:\n      chart: *app\n      interval: 10m\n      sourceRef:\n        kind: HelmRepository\n        name: community-charts\n        namespace: ai-system\n      version: 1.16.10\n  valuesFrom:\n    - kind: ConfigMap\n      name: n8n-values\n    - kind: Secret\n      name: n8n-values-secret\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/app/helmrepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: community-charts\nspec:\n  interval: 2h\n  url: https://community-charts.github.io/helm-charts\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: n8n\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'n8n.${CLUSTER_DOMAIN}'\n    - 'webhook.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: n8n\n          port: 5678\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: ai-system\n\nresources:\n  - helmrelease.yaml\n  - helmrepository.yaml\n  - httproute.yaml\n\nconfigMapGenerator:\n  - name: n8n-values\n    files:\n      - values.yaml=./values.yaml\n\nsecretGenerator:\n  - name: n8n-values-secret\n    namespace: ai-system\n    files:\n      - values.yaml=values.enc.age.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n  - kind: Secret\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/app/values.enc.age.yaml",
    "content": "sops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtbnZ2TXZqekZMbFYyeEda\n        L1dZdTBMWkMyZGtSUHJGYmQzaUttSnR3eDFzCjRnUFJkMWZlUW5qMjE0NnZOMmJW\n        eFRGZU9Ha3I4eXcrYlpyNFRkOU9YSjQKLS0tIDlBS09nOTJmRFE0UkpycW5vRits\n        T0VlSmpUU3IrWUVBa3U4S0J3WFNlbnMKleb2FhWSwssCRV5f8CB2Y1HpmRx/M4eQ\n        mtyduWrryJZmfKdJzDv/O1qiIF54TWS1RrDuGKK/CcWGn5zK8RhOXA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:20:16Z\"\n  mac: ENC[AES256_GCM,data:KmFA+P5OgtUBEmwddvbTe52MHOMWwt6kCC0xFJa1KvQounqlVr5JGDyzoD4fcx7ylF6eN2r1tjd2XKojtkPh+J2ULqaaPevK4DaonjnVFqz1rOkTp/aAAzfBQbCOjvz7+scJBk8Js0CBUSv3lDKmV1fEgI1ebq9kyyKdAJc7i5w=,iv:dIWlyA1uUuuI5u8bnRiAOmur/3ODGPCqjQqC9wI9LhY=,tag:xPmqDn1iRxnfXcRtx7yIrw==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/app/values.yaml",
    "content": "---\nwebhook:\n  url: \"https://webhook.${CLUSTER_DOMAIN}\"\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/n8n/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: n8n\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/n8n/app\"\n  wait: false\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: n8n\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: ai-system\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/ollama/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: ollama\nspec:\n  interval: 1h\n  chart:\n    spec:\n      chart: ollama\n      version: 1.56.0\n      sourceRef:\n        kind: HelmRepository\n        name: ollama-charts\n        namespace: flux-system\n      interval: 10m\n  values:\n    replicaCount: 1\n    ollama:\n      gpu:\n        enabled: false\n      models:\n        pull:\n          - qwen2.5:3b\n    resources:\n      requests:\n        cpu: 500m\n        memory: 4Gi\n      limits:\n        memory: 8Gi\n    persistentVolume:\n      enabled: true\n      storageClass: ceph-block\n      size: 30Gi\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/ollama/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: ollama\n  namespace: ai-system\nspec:\n  parentRefs:\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'ollama.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: ollama\n          port: 11434\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/ollama/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/ollama/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: ollama\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/ollama/app\"\n  wait: true\n  dependsOn:\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: ollama\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/open-webui/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: open-webui\nspec:\n  interval: 1h\n  chart:\n    spec:\n      chart: open-webui\n      version: 14.5.0\n      sourceRef:\n        kind: HelmRepository\n        name: open-webui-charts\n        namespace: flux-system\n      interval: 10m\n  values:\n    ollama:\n      enabled: false\n    pipelines:\n      enabled: false\n    websocket:\n      enabled: false\n    ollamaUrls:\n      - \"http://ollama.ai-system.svc.cluster.local:11434\"\n    persistence:\n      enabled: true\n      storageClass: ceph-block\n      size: 8Gi\n    resources:\n      requests:\n        cpu: 100m\n        memory: 256Mi\n      limits:\n        memory: 2Gi\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/open-webui/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: open-webui\n  namespace: ai-system\nspec:\n  parentRefs:\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'open-webui.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: open-webui\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/open-webui/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/ai-system/open-webui/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: open-webui\n  namespace: ai-system\nspec:\n  path: \"./apps/base/ai-system/open-webui/app\"\n  wait: true\n  dependsOn:\n    - name: ollama\n      namespace: ai-system\n  targetNamespace: ai-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: open-webui\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app crossplane\n  namespace: crossplane-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: crossplane\n  values:\n    metrics:\n      enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: crossplane-system\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: crossplane\n  namespace: crossplane-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 2.1.3\n  url: oci://xpkg.upbound.io/upbound/crossplane\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: crossplane\n  namespace: crossplane-system\nspec:\n  path: \"./apps/base/crossplane-system/crossplane/app\"\n  wait: true\n  targetNamespace: crossplane-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: crossplane\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: crossplane-providers\n  namespace: crossplane-system\nspec:\n  path: \"./apps/base/crossplane-system/crossplane/providers\"\n  wait: true\n  dependsOn:\n    - name: crossplane\n      namespace: crossplane-system\n  targetNamespace: crossplane-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: crossplane-providers\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/packages/gitops/composition.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/apiextensions.crossplane.io/composition_v1.json\napiVersion: apiextensions.crossplane.io/v1\nkind: Composition\nmetadata:\n  name: xgitopsclusters.gcp.xunholy.io\n  labels:\n    provider: gcp\n    gitops: flux\nspec:\n  writeConnectionSecretsToNamespace: crossplane-system\n  compositeTypeRef:\n    apiVersion: xunholy.io/v1alpha1\n    kind: XGitOpsCluster\n  patchSets:\n    - name: metadata\n      patches:\n        - fromFieldPath: metadata.labels\n        - fromFieldPath: metadata.annotations\n  resources:\n    - base:\n        apiVersion: container.gcp.upbound.io/v1beta1\n        kind: Cluster\n        spec:\n          forProvider:\n            location: us-central1\n            ipAllocationPolicy:\n              - {}\n            enableAutopilot: true\n          writeConnectionSecretToRef:\n            namespace: crossplane-system\n      patches:\n        - fromFieldPath: \"metadata.uid\"\n          toFieldPath: \"spec.writeConnectionSecretToRef.name\"\n          transforms:\n            - type: string\n              string:\n                fmt: \"%s-cluster\"\n        - fromFieldPath: spec.writeConnectionSecretToRef.namespace\n          toFieldPath: spec.writeConnectionSecretToRef.namespace\n      # The control plane supplies the 'kubeconfig' connection secret key, which\n      # is required by the XR.\n      connectionDetails:\n        - fromConnectionSecretKey: kubeconfig\n    - base:\n        apiVersion: helm.crossplane.io/v1beta1\n        kind: ProviderConfig\n        spec:\n          credentials:\n            source: Secret\n            secretRef:\n              key: kubeconfig\n          identity:\n            type: GoogleApplicationCredentials\n            source: Secret\n            secretRef:\n              name: gcp-credentials\n              key: credentials.json\n      patches:\n        - fromFieldPath: spec.id\n          toFieldPath: metadata.name\n        - fromFieldPath: spec.writeConnectionSecretToRef.namespace\n          toFieldPath: spec.credentials.secretRef.namespace\n        # This ProviderConfig uses the above GKE cluster's connection secret as\n        # its credentials secret.\n        - fromFieldPath: metadata.uid\n          toFieldPath: spec.credentials.secretRef.name\n          transforms:\n            - type: string\n              string:\n                fmt: \"%s-cluster\"\n        - fromFieldPath: spec.writeConnectionSecretToRef.namespace\n          toFieldPath: spec.identity.secretRef.namespace\n      readinessChecks:\n        - type: None\n    - base:\n        apiVersion: helm.crossplane.io/v1beta1\n        kind: Release\n        spec:\n          rollbackLimit: 3\n          forProvider:\n            namespace: flux-system\n            chart:\n              name: flux2\n              repository: https://fluxcd-community.github.io/helm-charts\n              version: \"2.7.0\"\n            values:\n              imageautomationcontroller:\n                create: false\n              imagereflectorcontroller:\n                create: false\n      patches:\n        - fromFieldPath: metadata.uid\n          toFieldPath: metadata.name\n          transforms:\n            - type: string\n              string:\n                fmt: \"%s-flux2\"\n        - fromFieldPath: spec.id\n          toFieldPath: spec.providerConfigRef.name\n    - base:\n        apiVersion: helm.crossplane.io/v1beta1\n        kind: Release\n        spec:\n          rollbackLimit: 3\n          forProvider:\n            namespace: flux-system\n            chart:\n              name: flux2-sync\n              repository: https://fluxcd-community.github.io/helm-charts\n              version: \"1.4.0\"\n      patches:\n        - fromFieldPath: metadata.uid\n          toFieldPath: metadata.name\n          transforms:\n            - type: string\n              string:\n                fmt: \"%s-flux2-sync\"\n        - fromFieldPath: spec.id\n          toFieldPath: spec.providerConfigRef.name\n        - fromFieldPath: spec.parameters.repository\n          toFieldPath: spec.forProvider.values.gitRepository.spec.url\n        - fromFieldPath: spec.parameters.branch\n          toFieldPath: spec.forProvider.values.gitRepository.spec.ref.branch\n        - fromFieldPath: spec.parameters.path\n          toFieldPath: spec.forProvider.values.kustomization.spec.path\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/packages/gitops/crossplane.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/meta.pkg.crossplane.io/configuration_v1.json\napiVersion: meta.pkg.crossplane.io/v1\nkind: Configuration\nmetadata:\n  name: gitops\n  annotations:\n    meta.crossplane.io/maintainer: Michael Fornaro (@xUnholy)\n    meta.crossplane.io/source: github.com/xunholy/k8s-gitops/tree/main/packages/gitops\n    meta.crossplane.io/license: MIT\n    meta.crossplane.io/description: My example of using crossplane\nspec:\n  dependsOn:\n    - provider: xpkg.upbound.io/upbound/provider-gcp:v0.30.0\n      version: \">=v0.30.0\"\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/packages/gitops/definition.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/apiextensions.crossplane.io/compositeresourcedefinition_v1.json\napiVersion: apiextensions.crossplane.io/v1\nkind: CompositeResourceDefinition\nmetadata:\n  name: xgitopsclusters.xunholy.io\nspec:\n  group: xunholy.io\n  names:\n    kind: XGitOpsCluster\n    plural: xgitopsclusters\n  claimNames:\n    kind: GitOpsCluster\n    plural: gitopsclusters\n  connectionSecretKeys:\n  - kubeconfig\n  versions:\n  - name: v1alpha1\n    served: true\n    referenceable: true\n    schema:\n      openAPIV3Schema:\n        type: object\n        properties:\n          spec:\n            type: object\n            properties:\n              id:\n                type: string\n                description: ID of this Cluster that other objects will use to refer to it.\n              parameters:\n                type: object\n                properties:\n                  repository:\n                    description: The repository that will be synced via GitOps\n                    type: string\n                    default: \"https://github.com/xunholy/k8s-gitops\"\n                  branch:\n                    type: string\n                    description: The Git reference to checkout and monitor for changes\n                    default: \"main\"\n                  path:\n                    type: string\n                    description: Path to the directory containing the kustomization.yaml\n                required:\n                - repository\n                - path\n            required:\n            - parameters\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/providers/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - provider.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/crossplane/providers/provider.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/pkg.crossplane.io/provider_v1.json\napiVersion: pkg.crossplane.io/v1\nkind: Provider\nmetadata:\n  name: provider-gcp-gke\nspec:\n  package: xpkg.upbound.io/upbound/provider-gcp-gke:v1.1.0\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/pkg.crossplane.io/provider_v1.json\napiVersion: pkg.crossplane.io/v1\nkind: Provider\nmetadata:\n  name: provider-gcp-gkehub\nspec:\n  package: xpkg.upbound.io/upbound/provider-gcp-gkehub:v1.1.0\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/pkg.crossplane.io/provider_v1.json\napiVersion: pkg.crossplane.io/v1\nkind: Provider\nmetadata:\n  name: provider-helm\nspec:\n  package: xpkg.upbound.io/crossplane-contrib/provider-helm:v0.18.1\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/pkg.crossplane.io/provider_v1.json\napiVersion: pkg.crossplane.io/v1\nkind: Provider\nmetadata:\n  name: provider-github\nspec:\n  package: xpkg.upbound.io/coopnorge/provider-github:v0.12.0\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/examples/example.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/xunholy.io/gitopscluster_v1alpha1.json\napiVersion: xunholy.io/v1alpha1\nkind: GitOpsCluster\nmetadata:\n  name: gitops-cluster\n  namespace: crossplane-system\nspec:\n  id: raspbernetes\n  parameters:\n    repository: https://github.com/xunholy/k8s-gitops\n    branch: main\n    path: \"kubernetes/clusters/cluster-00\"\n  compositionSelector:\n    matchLabels:\n      provider: gcp\n      gitops: flux\n  writeConnectionSecretToRef:\n    name: gitops-cluster-connection\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/examples/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  # - project.yaml Creates an example GCP project\n  - providerconfig.yaml   # providerConfig has a dependency on the GCP keys stored in crossplane-system; And the provider CRDs being installed.\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/examples/providerconfig.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gcp.upbound.io/providerconfig_v1beta1.json\napiVersion: gcp.upbound.io/v1beta1\nkind: ProviderConfig\nmetadata:\n  name: default\nspec:\n  projectID: raspbernetes\n  credentials:\n    source: Secret\n    secretRef:\n      namespace: crossplane-system\n      name: gcp-credentials\n      key: credentials.json\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/examples/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: gcp-credentials\n  namespace: crossplane-system\ndata:\n  credentials.json: ENC[AES256_GCM,data:PbCYUHgm17s56QoR3JhGCH89R5ehk3/38dszzM/mcRzmaoh5Pm3P2JOmE9EkwO0LL6JDYJHYSY5XaVex0ozSCkpAFBdpZC8Rrl+ZzFCglwZ0eC+VoVurTxFCs9lNzIOBcWIJwllvzgZwSlMH5xDIEZzuwJiV/qDntsQh5HuVyGDdLrejcVv7lhZOBwDp6/Du9ToOYonUCIIc808mtPAS/ShZgD3v6xI+4kbpUO9cbjwqRFEi+QoqjBdM1kZyJ2OkIj5IXlxpFxc1gakMfXqn4l7tH/EogUlN8UJSWgDvwBhiyt0qvSIkCyiblH/dl8NHEIvei+LOkcK2c5eJ2ypnUB8OR/fp695UEDK21d9MwM2sstdBMlDwByi4wbQYWRxrjwJfrxpZHuGnyP5GhpLg/HIJMrnd7QUohL56lplPxqOxSVtIXu8jUpijCjN5wKkILPEs4HZYMDYRLYwUYvDiT8y2mew2ywjVMZoBihimZuSfZ8QioBfBs+sTXy9oJ+3wm6VqosnOmaZWpZvnz8oigwAXYa78N38zMklyz+XV92eNZ+eHHGq00xFRuXwEsHn5tHqU54Eu+07oAS8e3kiJrj0CoBKLTLRC7aVTw3OxvqH9mY2nApPrmCEyVvFldUU5ejpyOx1ct7Z9sK/ZpN+HHywXW9SQORGj/djd4OcPtoQZkndPs/w0Aczxxt7PsPd7XUBnubvxW4EZBKlQybIiAbWC4hs2YKVkd87YElgNWseH5sJkRG9KUb3RkYy5eXz4L1pP2UMZ92HKiBHOEkINE7mIqbkC3Z1JJbFn2MoTHOnilZnbGnUBSG2v9mWZP31PqR30MvW6gbeLO0o7H3uwkWLXvIoes5gLBx7DZGjeN0YiZfwZQoMswLdSgcY/Wnq5XPhktQGzzVsckdChohHoWvPfxRKQCoiv0DsNAQEd6JupW7g4f6Ly6oR9jyyGId+kSZWdbAJq17fh5GUx9CThJSxaubp7rcQDTl7f/ZISqSVo5qzbOMkwsNQtABmgI5m3JddEjZMSLGHLtg9FULe3BsbVX5JiMe7OhQ0qUgNawg3A+W2bJM5pyWwN9XI7XbVHH/Feolj/b0BqxRBTf5LIOuEZiYUTXuKBvsv0QTQ0CPy1FC4lYZ8ClHLGO45m38o31y14YK4E4YLj4p0TOtvW1XcSEZlDvkRjIgybVb2/Am3I/PWz0vlDjyRs5bHe/GzRXEfCDJLA4bDvyMpCYr8kYGeLeQOMTwtvlIzx5i8FUovg1o/XsUVk6+he2SeEa+awYKCZVHcaspdQwh8BRcTACCrT87a/Zmj5u9NWBCN4tfMaMUWgDwEITix77hNy547w0U9Qf3kJTmAPC8B+uFXisJy8EpfYdd6JcRqqsl1Qro4KtuF9ppCyg5LWOrCjHZG5pII9d0VAesGRHkGxi4TmakfkiVxOf0LM7G09FujZYTKUfeFxYnRBHRRJ6pLo7g1vs3TDiY2HUBJKp50Q2cPHjQI4nkFXwRiJSMoVH7CUsTUoUQZEkKWtE4wBMIOgESNJyf0mWytw+F895eMaATPG2UYW2Q8x4e/EOJabyifVWJgzMqqo4km23DRbyot37lQUwIrm+ovLOkK7iW86XnYfzqovyiw9nDJfy75nn3Q9PHdesZ3GPOPuGBN3v5Yjc/QBkap6sVo0jVE8UzB1r8oytGS2wcxw6uScF9tMaarxS+LXifH2/fkiki1vHjZmvpA83iCL2NBzyLTG/M1T1rktk4FKVZVi1DNkwfsemqWtoB1C+ecsLbhH6G92Jk1wTizsGX9zlspXUbSRMSh27zJoVqS+EJfk1JD3y3tigoh8aSGJnL2gnEFj4gfldf64pOw6Q9pNpaP2Puyjjp5F00efqlRQl3tW3PQWZC2mWE/oxwcGlP4VLnYUlxdoP3LVB2B7G0RMghgc92oug8oSWNnpQRnsiErXOgDn4PuKBOQNRwGIXtgKR/wnvUSPl+HuObhN4gT06yfY1EexRc2qh1c5qfChC595x50FKtYkxkfdS7DaYOqoO8cLZQtlZyMJ/cBQ+aB9JaFlC+Cp/6IF41yKKcYG5j3YSkxH2Tum14p1C+CfYJXefZITObX42SweMb2IKySdyJpygiVnkXJrQ11nTbk9HMlwgfaxW75SoYqih+LGva+rNJRRf6y+cr3ZuUgQ+Sld5SPL82YcVhDlhklRH3PLKd8RG2dZZhtMWigasBX00aY/26EJV4qtmMp43FaV+woIhZxQ8XaQ8Ry61i5+M4gjW8j/7rOwYYyfKpPFo1c7a6YZJrsRpt4K+wTHiQ13NjtMumAjvUnSWk66hH39Z0XbDntsxe6lPyFuPEgsynwP1vCzKCicDFIlLoH02Yt/yfooS7IJgoOH3sX0IHUVx8sozgwTeiUTcykaAYN3L/bGsGRTWSyJWXxk4gWFIEfSb8ifzMofmvOzI0nm2gGxvuAapbifYn/+3IECK/VWcipTme85rm57FWJs2O7CSeGAM7C8DSq7JtoffNJsbmzJ5WjwM8KkI7bGTrEig7WhTSdZV1gvwjJbpmTSxKXyAyTVncC3D2pE03PKZ1LbTydrAGVtbvm8qgc4vHP1U1vlFUXUnQuALV+WcOKVQBNIOYtU7Uk+o5nTJkjqHdsVD3V7atXqhBJaiJpVfv4FZ2noOSQL7HBgEFzuMU1x5jYqLd1uB767svibqBodaeVNCTyoUKuVO2i62oE/LnbR4iF0cOkLoqSkz2iGU8WnkcSxYjqhROAR4gu2O16VQp8kU0KhtL6ftuzNEQVQ5HKV9BOSqQy+Rq+M/YA7k/U9wcSRPk3Pfe4a4Hgs8IGQQudgk1DCqymzxU6TheYbeBHLsDS+mnWL7C0U6qa9CQ+Xjz1SAamk4q9rit3m7EZfdf3rcurEvqkNDTv/ornezfBgwobHuLv4htrdFp/JnRvmDybL+UIwiuM+m8H2bIo/uQL7HGKOIm+mWS10FuDeGiZ4S1pt89QxyOGdpayBUc38gNqEQxTOfgSekLKltJvos5aE3Y+OFQwSSctuzA+WlXPsdEWJiBwxJGnVoWd45AB09JlwmJj8/jgbEuRivEWPb+xPpJvtSJworVkQPLuT/8LtIdOWETJM5nTuvUZi/H/ZSWuaZKAcXnx6uxB844epk+Kktf2jm+NQ93jMObIH7yd/EdqqEa3pwtqg5Zj4J/GEmRkut9XW+9MTfEXQWuvM1PRPa2xa45rz9Kg6i95bk57R9D91LFcgqJI33DhRkemtVyMnhhyt8Rh6jCiBXvraBnozvhBlkgom7a22wWvdgkRutB8A5p9giCoyq9ltIh/djuYl/Qg4dkWDeGLY0qkLOYutaqHUp64CU7+QY30EECwu7RidcRhCtNMLnZ6CKPrsZZV2revWGiwkSQYsjs7WVQCq6dTVMAVVtRjD+XCYYpXciJhVXUP2F8SmiUSKuMlz/+fT8tnxn/B7+AzMVlWAHsSbef2DPwc4uAsqVyCuUHwNcpyqNh+ha7QDsblUftBndqoglX/0/JxeyybnPp1pQfkvdDfHi7VyIdxqfL34gUkdfJyUD7+gSICqRkkwyFzErWyjcN9Fsgd+AxKEG2XH5DViUXBqMcThzcwMEn/KutFDKLqENGeWBG/JFUw6KrmfKZIhoWUArR8c0ycTKZQCGiGA7MxtVT5CEtVcpVl5UlWyezO4Zf+zQJWopuW3CTb+gFGRNn0hlLJsUvcvmT3EpKspwk/ubirDX5DQoS2ck2oPYGXnO+gqq+Xf3ZVv+z6SZ6i8Bdx1BCg67kJwmu8HtHC2wN4Msqg05ED95mUbdSK1KxEg2dJWnbpQ13pvovLFrMTEf7bsU11ylWFSOm7+RbsZdUygqaAH8dWu0mZe17x19AXczN/nvFVWSuRvKMgCwlOVNgVHu6wTTX3r2qVc9GCM2sO9FUD4ujeX01DbuDyUJpQIp2dv5Itd6I1w7b20WtsQ2J8CdUCgjyZgXo1/Z/k6DzEViLqFFnQmd51kdqUhWpQgxlpaTncNlZn4YHC6DTrv91TFzwoPHHOsSsP5zP2In3JHE3hf3qDxiFFu311lhbbUYgF6/sK2/lGcoDdh34EMwmokZjUV9tXZCs8=,iv:9TKIRMl2rTuNRXt95gpsVY/VxFBDO3Zj1NVPtTcAPQo=,tag:ZFC2mXiNH+uUF0TjvlvrXA==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2S1BmMVJ1Z3VGVnhMQXoy\n        L0pIa01zUTc0eWRhUFErWGRKaVJma0VEOVVVCjlna1ByaklDUWEwR1hLL3ZJU0VT\n        WVl0ZytFalUza1ZYdS9VQk8vQUJTRFUKLS0tIE5vVHYxS0MxMkUyTFZrWkUraFZB\n        c3dEZzB6Z2didkZqOXh4RUkrSmM2eEUK+vajIT1DULbYE4TFn2/+/DIsKStIZrdY\n        QzXbh6PC04l8cY4n/MUbj4kjUwUqQLCzgS7fT8z1pVzHJHWSJ4+HEg==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:21:04Z\"\n  mac: ENC[AES256_GCM,data:uECxrCqQ3Gifr2iiKcIQlMP1LpPA6nMmNKuqnHCM09rX03BmK5UTmOK3wBSUiSJvhPPszeZ+ZdxrcmxG0oj43PUnLtuGD4MPGZPAuiR7PG949dyjLgwPLSZ217c3g1G/CCSwP+RwoPfdfBJazT7VNOAqbwp0v96hBwHN5b9G6WE=,iv:jlU6ffX5XIARksOt3BIspOh+rzkRaSxzEadBYtU/bX0=,tag:woF5C8D3ZBk7nXbS8Df6aQ==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: crossplane-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/crossplane-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: crossplane-system\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/democratic-csi/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app democratic-csi\n  namespace: democratic-csi\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: *app\n      interval: 10m\n      sourceRef:\n        kind: HelmRepository\n        name: democratic-csi-charts\n        namespace: flux-system\n      version: 0.15.1\n  dependsOn:\n    - name: snapshot-controller\n      namespace: kube-system\n  valuesFrom:\n    - kind: ConfigMap\n      name: democratic-csi-values\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/democratic-csi/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - secret.enc.age.yaml\n\nconfigMapGenerator:\n  - name: democratic-csi-values\n    namespace: democratic-csi\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/democratic-csi/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/democratic-csi/app/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: driver-config\n  namespace: democratic-csi\ntype: Opaque\nstringData:\n  driver-config-file.yaml: ENC[AES256_GCM,data:9LxTOPdoL94u9MbztY3vqQF8VY3LsCqcECMt0PXFkh9b26oEJ+lCuFxKYHMvBpdlGSJpXMzhkhHy7I+FhsAdjnYHXvOuowSaJ7C3+xduqfxS7woRXgh8Kwat/AgE2HtQWxn/NPaqNlDAod6Exqa0Qrh8gseRkjxXkGzM1EdotZuMHD+2kdCLEiFWtEwmzrKxXGQbPscigWabGyTpbCSrHgJgd67bB2Pcgr0QLKlD6PtYHDzD2B0kLuflvYhGZDDhK0Npw9X5/Ah4Wj1bZQrqkVOIBU6sgCA/aW+ZnPt+Tq90iqW8VU+ICereDQixYiVJMbYliwD7dSngC6gNxbJQ4pbGCc9aTkpMcCDnqjUrD0xKJb1VI1BNa8/aIvUN4SiuVofTkpKVlfXpOtfYWNEPMKZVmLMJcAqW0Ge+ivqJ3kIg9AcXdtMiRlL20pKqxC+RTb1Ng2H1ytN+yWWelBr9PlfnNPbfoNSp1RAghcpj+R23BI5GcZHZ7j/6PvTmAgoM0MBhL09ob4KN4btTFhadfxZeb3VJxG7zN/2yAgVQfu3VIDvwOGMFYUO1NB1TdFWY8hq3VmFMavt7fYsyxfXhP+Bym8NJdEsmHUfrpVr3HzP6w5iZbDAEIurjIKkT2KOjtgaxKZgdigI2vLP4fKeSm7fV/Sv7euFf+lTSdGLMuf0DUmxdUhCylY/VmxI2BPU4QymXuVTmle8PvQMo+WC5dHdbK/SdMs7qGj9pFkRYggbsTkv4URtqn72UUgmWoRvQZpS8yyeykeX1QOZRoiTk8TuSH87m5BgI1sd+31g+jrUjI4y7pRnG0u5QRZYyG2EelE/Adpj0nZQG+mJtCuIfk6TsN1SiD4o7V6jssz41KthjLnlTWWjlECvciQBk/ocuAb9V/PeTrZZb0/XdN3Qh0SfrTYA6HGs4PeBbpeVCMcDFSkqhf5so0rFsIsq9hcrMW8StOg==,iv:6AKoDWA/gkDLn562nhMOJaCxGaJG2v+BY4/yEzyjyKo=,tag:fqw1QPgjZUnhLgdo+QDWyw==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZa05aZFRqS2dSb09FeE4x\n        S0JaZUhnaStVUStGa05wZGIrYkxieUNOTVVnCmpCdlBJNTBDVDRCbzFjQ1Z3OW1J\n        Zkt2a1JtYlY4Z2M2QXYxYlVxTlRWZ0EKLS0tIGFFZEordW9STjJWaFI4N1F2RDBz\n        NkpCcEo0ZXpEUVM3dkdlakY1ZlE5R0EKvnhcw/TAnL/Z46q0JWgexRn1D6ErnmhM\n        j6q1i6K5+g3XfDvGh/zQMpE12kLBQgdP7a1OVVry8vSPrfF0SJ91MQ==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:21:04Z\"\n  mac: ENC[AES256_GCM,data:9qq99yJD6A6/mbOTMLHMcCEeBR64a45ACgSBveSSn4GUSBZYm2Yc2VhXoxHHXqjwPs90gwKeAvhW07XPUNd8zkMqW/WuIruvvIpX4zTaclqTH2WQSgt1xigH8IJRZqIvHgs+adHvGTQMd0E4fFpCkSc2MpTNnEeKkx8WDj8q4TY=,iv:Gwr0jqxkGPn088zx8q9SZofEcH/hukNozQzFwhue8Fg=,tag:bBCV7jBXtZwt6SLwffgR/Q==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/democratic-csi/app/values.yaml",
    "content": "controller:\n  priorityClassName: platform-cluster-critical\ncsiDriver:\n  name: \"org.democratic-csi.iscsi\"\nnode:\n  driver:\n    extraEnv:\n    - name: ISCSIADM_HOST_STRATEGY\n      value: nsenter\n    - name: ISCSIADM_HOST_PATH\n      value: /usr/local/sbin/iscsiadm\n    iscsiDirHostPath: /var/iscsi\n    iscsiDirHostPathType: \"\"\n  hostPID: true\n  priorityClassName: platform-node-critical\n  tolerations:\n  - key: \"node-role.kubernetes.io/control-plane\"\n    operator: \"Exists\"\n    effect: \"NoSchedule\"\ndriver:\n  existingConfigSecret: driver-config\n  config:\n    # please see the most up-to-date example of the corresponding config here:\n    # https://github.com/democratic-csi/democratic-csi/tree/master/examples\n    # YOU MUST COPY THE DATA HERE INLINE!\n    driver: freenas-api-iscsi\nstorageClasses:\n- name: truenas-iscsi-csi\n  defaultClass: false\n  reclaimPolicy: Retain\n  volumeBindingMode: Immediate\n  allowVolumeExpansion: true\n  parameters:\n    # for block-based storage can be ext3, ext4, xfs\n    # for nfs should be nfs\n    fsType: ext4\n    detachedVolumesFromSnapshots: \"false\"\n  mountOptions: []\n  secrets:\n    controller-expand-secret: null\n    controller-publish-secret: null\n    node-publish-secret: null\n    node-stage-secret: null\n    provisioner-secret: null\nvolumeSnapshotClasses:\n- name: truenas-iscsi\n  deletionPolicy: Retain\n  parameters:\n    detachedSnapshots: \"true\"\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/democratic-csi/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: democratic-csi\n  namespace: democratic-csi\nspec:\n  path: \"./apps/base/democratic-csi/democratic-csi/app\"\n  wait: true\n  targetNamespace: democratic-csi\n  sourceRef:\n    kind: ExternalArtifact\n    name: democratic-csi\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: democratic-csi\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/democratic-csi/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: democratic-csi\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/development/backstage/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app backstage\n  namespace: development\nspec:\n  interval: 15m\n  chart:\n    spec:\n      chart: backstage\n      version: 2.7.0\n      sourceRef:\n        kind: HelmRepository\n        name: backstage-chart\n        namespace: flux-system\n  values:\n    serviceAccount:\n      create: true\n    metrics:\n      serviceMonitor:\n        enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/development/backstage/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: backstage\n  namespace: development\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'backstage.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: backstage\n          port: 7007\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/development/backstage/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/development/backstage/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: backstage\n  namespace: flux-system\nspec:\n  path: \"./apps/base/development/backstage/app\"\n  wait: true\n  targetNamespace: development\n  sourceRef:\n    kind: ExternalArtifact\n    name: backstage\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/development/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: development\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/development/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: development\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/development/open-feature-operator/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: open-feature-operator\nspec:\n  interval: 1h\n  chart:\n    spec:\n      chart: open-feature-operator\n      version: v0.9.1\n      sourceRef:\n        kind: HelmRepository\n        name: openfeature-charts\n        namespace: flux-system\n      interval: 10m\n  values:\n    defaultResources:\n      requests:\n        cpu: 10m\n        memory: 64Mi\n      limits:\n        memory: 128Mi\n"
  },
  {
    "path": "kubernetes/apps/base/development/open-feature-operator/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/development/open-feature-operator/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: open-feature-operator\n  namespace: development\nspec:\n  path: \"./apps/base/development/open-feature-operator/app\"\n  wait: true\n  dependsOn:\n    - name: cert-manager\n      namespace: network-system\n  targetNamespace: development\n  sourceRef:\n    kind: ExternalArtifact\n    name: open-feature-operator\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/development/vcluster/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app vcluster\n  namespace: development\nspec:\n  interval: 15m\n  chart:\n    spec:\n      chart: vcluster-k8s\n      version: 0.19.10\n      sourceRef:\n        kind: HelmRepository\n        name: loft-charts\n        namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/development/vcluster/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/development/vcluster/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: vcluster\n  namespace: flux-system\nspec:\n  path: \"./apps/base/development/vcluster/app\"\n  wait: true\n  targetNamespace: development\n  sourceRef:\n    kind: ExternalArtifact\n    name: vcluster\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: external-secrets\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  configMapRef:\n    name: external-secrets-dashboard\n    key: external-secrets.json\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app external-secrets\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: external-secrets\n  valuesFrom:\n    - kind: ConfigMap\n      name: external-secrets-values\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n  - pdb.yaml\n\nconfigMapGenerator:\n  - name: external-secrets-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: external-secrets\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 2.5.0\n  url: oci://ghcr.io/external-secrets/charts/external-secrets\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/app/pdb.yaml",
    "content": "---\napiVersion: policy/v1\nkind: PodDisruptionBudget\nmetadata:\n  name: external-secrets-webhook\nspec:\n  minAvailable: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/instance: external-secrets\n      app.kubernetes.io/name: external-secrets-webhook\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/app/values.yaml",
    "content": "priorityClassName: platform-cluster-critical\nleaderElect: true\nserviceMonitor:\n  enabled: true\ngrafanaDashboard:\n  enabled: true\ncertController:\n  serviceMonitor:\n    enabled: true\nwebhook:\n  replicaCount: 2\n  serviceMonitor:\n    enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/external-secrets/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: external-secrets\n  namespace: external-secrets\nspec:\n  path: \"./apps/base/external-secrets/external-secrets/app\"\n  wait: true\n  targetNamespace: external-secrets\n  sourceRef:\n    kind: ExternalArtifact\n    name: external-secrets\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: external-secrets\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: external-secrets\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/onepassword/app/clustersecretstore.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/clustersecretstore_v1.json\napiVersion: external-secrets.io/v1\nkind: ClusterSecretStore\nmetadata:\n  name: onepassword\nspec:\n  provider:\n    onepassword:\n      connectHost: http://onepassword.external-secrets.svc.cluster.local\n      vaults:\n        kubernetes: 1\n      auth:\n        secretRef:\n          connectTokenSecretRef:\n            name: onepassword-connect-token\n            namespace: external-secrets\n            key: token\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/onepassword/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: onepassword\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: onepassword-secret\n    template:\n      data:\n        1password-credentials.json: '{{ .OP_CREDENTIALS_JSON }}'\n        token: '{{ .OP_CONNECT_TOKEN }}'\n  dataFrom:\n    - extract:\n        key: 1password\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/onepassword/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app onepassword\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  valuesFrom:\n    - kind: ConfigMap\n      name: onepassword-values\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/onepassword/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - clustersecretstore.yaml\n  - externalsecret.yaml\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: onepassword-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/onepassword/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/onepassword/app/values.yaml",
    "content": "controllers:\n  onepassword:\n    strategy: RollingUpdate\n    annotations:\n      reloader.stakater.com/auto: \"true\"\n    containers:\n      api:\n        image:\n          repository: ghcr.io/1password/connect-api\n          tag: 1.8.2@sha256:fabf0a353791f7d70851767c6d58595eb386a86ba4ada4a8ca41b3668a096b5d\n        env:\n          XDG_DATA_HOME: &configDir /config\n          OP_HTTP_PORT: &apiPort 80\n          OP_BUS_PORT: 11220\n          OP_BUS_PEERS: localhost:11221\n          OP_SESSION:\n            valueFrom:\n              secretKeyRef:\n                name: connect-server-credentials\n                key: 1password-credentials.json\n        probes:\n          liveness:\n            enabled: true\n            custom: true\n            spec:\n              httpGet:\n                path: /heartbeat\n                port: *apiPort\n              initialDelaySeconds: 0\n              periodSeconds: 10\n              timeoutSeconds: 1\n              failureThreshold: 3\n          readiness:\n            enabled: true\n            custom: true\n            spec:\n              httpGet:\n                path: /health\n                port: *apiPort\n              initialDelaySeconds: 0\n              periodSeconds: 10\n              timeoutSeconds: 1\n              failureThreshold: 3\n        resources: &resources\n          requests:\n            cpu: 10m\n          limits:\n            memory: 64Mi\n        securityContext: &securityContext\n          allowPrivilegeEscalation: false\n          readOnlyRootFilesystem: true\n          capabilities: { drop: [\"ALL\"] }\n      sync:\n        image:\n          repository: ghcr.io/1password/connect-sync\n          tag: 1.8.2@sha256:3844a6410e119ccec72011737d5b46afe4be12cb0f54f681fe3ce999280449d8\n        env:\n          XDG_DATA_HOME: *configDir\n          OP_HTTP_PORT: &syncPort 8081\n          OP_BUS_PORT: 11221\n          OP_BUS_PEERS: localhost:11220\n          OP_SESSION:\n            valueFrom:\n              secretKeyRef:\n                name: connect-server-credentials\n                key: 1password-credentials.json\n        probes:\n          liveness:\n            enabled: true\n            custom: true\n            spec:\n              httpGet:\n                path: /heartbeat\n                port: *syncPort\n              initialDelaySeconds: 0\n              periodSeconds: 10\n              timeoutSeconds: 1\n              failureThreshold: 3\n          readiness:\n            enabled: true\n            custom: true\n            spec:\n              httpGet:\n                path: /health\n                port: *syncPort\n              initialDelaySeconds: 0\n              periodSeconds: 10\n              timeoutSeconds: 1\n              failureThreshold: 3\n        resources: *resources\n        securityContext: *securityContext\ndefaultPodOptions:\n  securityContext:\n    runAsNonRoot: true\n    runAsUser: 999\n    runAsGroup: 999\nservice:\n  app:\n    ports:\n      http:\n        port: *apiPort\npersistence:\n  config:\n    type: emptyDir\n    globalMounts:\n      - path: *configDir\n"
  },
  {
    "path": "kubernetes/apps/base/external-secrets/onepassword/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: onepassword\n  namespace: external-secrets\nspec:\n  path: \"./apps/base/external-secrets/onepassword/app\"\n  wait: true\n  targetNamespace: external-secrets\n  dependsOn:\n    - name: external-secrets\n      namespace: external-secrets\n  sourceRef:\n    kind: ExternalArtifact\n    name: onepassword\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/artifact-generator/artifactgenerator.yaml",
    "content": "---\napiVersion: source.extensions.fluxcd.io/v1beta1\nkind: ArtifactGenerator\nmetadata:\n  name: k8s-gitops\n  namespace: flux-system\nspec:\n  sources:\n    - alias: repo\n      kind: OCIRepository\n      name: flux-system\n  artifacts:\n    - name: actions-runner-scale-set\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/actions-runner-system/gha-runner-scale-set/app/\"\n          to: \"@artifact/apps/base/actions-runner-system/gha-runner-scale-set/app/\"\n    - name: adminer\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/adminer/app/\"\n          to: \"@artifact/apps/base/game-servers/adminer/app/\"\n    - name: autobrr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/autobrr/app/\"\n          to: \"@artifact/apps/base/home-system/autobrr/app/\"\n    - name: azerothcore\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/azerothcore/app/\"\n          to: \"@artifact/apps/base/game-servers/azerothcore/app/\"\n    - name: backstage\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/development/backstage/app/\"\n          to: \"@artifact/apps/base/development/backstage/app/\"\n    - name: bazarr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/bazarr/app/\"\n          to: \"@artifact/apps/base/home-system/bazarr/app/\"\n    - name: blackbox-exporter\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/blackbox-exporter/app/\"\n          to: \"@artifact/apps/base/observability/blackbox-exporter/app/\"\n    - name: cert-manager\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/cert-manager/app/\"\n          to: \"@artifact/apps/base/network-system/cert-manager/app/\"\n    - name: cilium\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/cilium/app/\"\n          to: \"@artifact/apps/base/kube-system/cilium/app/\"\n    - name: cloudflare-tunnel\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/cloudflare-tunnel/app/\"\n          to: \"@artifact/apps/base/network-system/cloudflare-tunnel/app/\"\n    - name: cmangos\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/cmangos/app/\"\n          to: \"@artifact/apps/base/game-servers/cmangos/app/\"\n    - name: cmangos-ptr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/cmangos-ptr/app/\"\n          to: \"@artifact/apps/base/game-servers/cmangos-ptr/app/\"\n    - name: crossplane-providers\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/crossplane-system/crossplane/providers/\"\n          to: \"@artifact/apps/base/crossplane-system/crossplane/providers/\"\n    - name: crossplane\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/crossplane-system/crossplane/app/\"\n          to: \"@artifact/apps/base/crossplane-system/crossplane/app/\"\n    - name: crowdsec\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/security-system/crowdsec/app/\"\n          to: \"@artifact/apps/base/security-system/crowdsec/app/\"\n    - name: democratic-csi\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/democratic-csi/democratic-csi/app/\"\n          to: \"@artifact/apps/base/democratic-csi/democratic-csi/app/\"\n    - name: descheduler\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/descheduler/app/\"\n          to: \"@artifact/apps/base/kube-system/descheduler/app/\"\n    - name: dex-k8s-authenticator\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/dex-k8s-authenticator/app/\"\n          to: \"@artifact/apps/base/network-system/dex-k8s-authenticator/app/\"\n    - name: dex\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/dex/app/\"\n          to: \"@artifact/apps/base/network-system/dex/app/\"\n    - name: echo-server\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/echo-server/app/\"\n          to: \"@artifact/apps/base/network-system/echo-server/app/\"\n    - name: emberstone-portal\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/emberstone-portal/app/\"\n          to: \"@artifact/apps/base/game-servers/emberstone-portal/app/\"\n    - name: enemy-territory\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/enemy-territory/app/\"\n          to: \"@artifact/apps/base/game-servers/enemy-territory/app/\"\n    - name: envoy-gateway\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/envoy-gateway/app/\"\n          to: \"@artifact/apps/base/network-system/envoy-gateway/app/\"\n    - name: external-dns-unifi\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/external-dns-unifi/app/\"\n          to: \"@artifact/apps/base/network-system/external-dns-unifi/app/\"\n    - name: external-dns\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/external-dns/app/\"\n          to: \"@artifact/apps/base/network-system/external-dns/app/\"\n    - name: external-secrets\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/external-secrets/external-secrets/app/\"\n          to: \"@artifact/apps/base/external-secrets/external-secrets/app/\"\n    - name: falco-exporter\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/security-system/falco-exporter/app/\"\n          to: \"@artifact/apps/base/security-system/falco-exporter/app/\"\n    - name: falco\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/security-system/falco/app/\"\n          to: \"@artifact/apps/base/security-system/falco/app/\"\n    - name: flux-instance-extras\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/flux-system/flux-instance/extras/\"\n          to: \"@artifact/apps/base/flux-system/flux-instance/extras/\"\n    - name: gatekeeper\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/security-system/gatekeeper/app/\"\n          to: \"@artifact/apps/base/security-system/gatekeeper/app/\"\n    - name: gha-runner-scale-set-controller\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/actions-runner-system/gha-runner-scale-set-controller/app/\"\n          to: \"@artifact/apps/base/actions-runner-system/gha-runner-scale-set-controller/app/\"\n    - name: grafana-instance\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/grafana/instance/\"\n          to: \"@artifact/apps/base/observability/grafana/instance/\"\n    - name: grafana\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/grafana/app/\"\n          to: \"@artifact/apps/base/observability/grafana/app/\"\n    - name: harbor\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/harbor/harbor/app/\"\n          to: \"@artifact/apps/base/harbor/harbor/app/\"\n    - name: home-assistant\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/home-assistant/app/\"\n          to: \"@artifact/apps/base/home-system/home-assistant/app/\"\n    - name: jellyseerr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/jellyseerr/app/\"\n          to: \"@artifact/apps/base/home-system/jellyseerr/app/\"\n    - name: kagent-crds\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/kagent/crds/\"\n          to: \"@artifact/apps/base/ai-system/kagent/crds/\"\n    - name: kagent\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/kagent/app/\"\n          to: \"@artifact/apps/base/ai-system/kagent/app/\"\n    - name: keda\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/keda/app/\"\n          to: \"@artifact/apps/base/kube-system/keda/app/\"\n    - name: kgateway-crds\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/kgateway/crds/\"\n          to: \"@artifact/apps/base/ai-system/kgateway/crds/\"\n    - name: kgateway\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/kgateway/app/\"\n          to: \"@artifact/apps/base/ai-system/kgateway/app/\"\n    - name: kguardian\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kguardian/kguardian/app/\"\n          to: \"@artifact/apps/base/kguardian/kguardian/app/\"\n    - name: kmcp-crds\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/kmcp/crds/\"\n          to: \"@artifact/apps/base/ai-system/kmcp/crds/\"\n    - name: kmcp\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/kmcp/app/\"\n          to: \"@artifact/apps/base/ai-system/kmcp/app/\"\n    - name: kopia\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/volsync-system/kopia/app/\"\n          to: \"@artifact/apps/base/volsync-system/kopia/app/\"\n    - name: kromgo\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/kromgo/app/\"\n          to: \"@artifact/apps/base/observability/kromgo/app/\"\n    - name: kube-prometheus-stack\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/kube-prometheus-stack/app/\"\n          to: \"@artifact/apps/base/observability/kube-prometheus-stack/app/\"\n    - name: kubelet-csr-approver\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/kubelet-csr-approver/app/\"\n          to: \"@artifact/apps/base/kube-system/kubelet-csr-approver/app/\"\n    - name: kyverno\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/security-system/kyverno/app/\"\n          to: \"@artifact/apps/base/security-system/kyverno/app/\"\n    - name: loki\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/loki/app/\"\n          to: \"@artifact/apps/base/observability/loki/app/\"\n    - name: metrics-server\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/metrics-server/app/\"\n          to: \"@artifact/apps/base/kube-system/metrics-server/app/\"\n    - name: minecraft-bedrock-broadcaster\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/minecraft-bedrock-broadcaster/app/\"\n          to: \"@artifact/apps/base/game-servers/minecraft-bedrock-broadcaster/app/\"\n    - name: minecraft-bedrock\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/minecraft-bedrock/app/\"\n          to: \"@artifact/apps/base/game-servers/minecraft-bedrock/app/\"\n    - name: minecraft-pixelmon\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/minecraft-pixelmon/app/\"\n          to: \"@artifact/apps/base/game-servers/minecraft-pixelmon/app/\"\n    - name: minecraft-proxy\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/minecraft-proxy/app/\"\n          to: \"@artifact/apps/base/game-servers/minecraft-proxy/app/\"\n    - name: minecraft-rcon-web\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/minecraft-rcon-web/app/\"\n          to: \"@artifact/apps/base/game-servers/minecraft-rcon-web/app/\"\n    - name: minecraft-router\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/minecraft-router/app/\"\n          to: \"@artifact/apps/base/game-servers/minecraft-router/app/\"\n    - name: minecraft\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/game-servers/minecraft/app/\"\n          to: \"@artifact/apps/base/game-servers/minecraft/app/\"\n    - name: mosquitto\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/mosquitto/app/\"\n          to: \"@artifact/apps/base/home-system/mosquitto/app/\"\n    - name: multus-networks\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/multus/networks/\"\n          to: \"@artifact/apps/base/network-system/multus/networks/\"\n    - name: multus\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/multus/app/\"\n          to: \"@artifact/apps/base/network-system/multus/app/\"\n    - name: n8n\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/n8n/app/\"\n          to: \"@artifact/apps/base/ai-system/n8n/app/\"\n    - name: nginx-ingress\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/nginx-ingress/nginx-ingress/app/\"\n          to: \"@artifact/apps/base/nginx-ingress/nginx-ingress/app/\"\n    - name: oauth2-proxy\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/network-system/oauth2-proxy/app/\"\n          to: \"@artifact/apps/base/network-system/oauth2-proxy/app/\"\n    - name: ollama\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/ollama/app/\"\n          to: \"@artifact/apps/base/ai-system/ollama/app/\"\n    - name: onepassword\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/external-secrets/onepassword/app/\"\n          to: \"@artifact/apps/base/external-secrets/onepassword/app/\"\n    - name: open-feature-operator\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/development/open-feature-operator/app/\"\n          to: \"@artifact/apps/base/development/open-feature-operator/app/\"\n    - name: open-webui\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/ai-system/open-webui/app/\"\n          to: \"@artifact/apps/base/ai-system/open-webui/app/\"\n    - name: otel\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/otel/app/\"\n          to: \"@artifact/apps/base/observability/otel/app/\"\n    - name: preview-system\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/preview-system/app/\"\n          to: \"@artifact/apps/base/preview-system/app/\"\n    - name: prowlarr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/prowlarr/app/\"\n          to: \"@artifact/apps/base/home-system/prowlarr/app/\"\n    - name: qbittorrent\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/qbittorrent/app/\"\n          to: \"@artifact/apps/base/home-system/qbittorrent/app/\"\n    - name: qui\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/qui/app/\"\n          to: \"@artifact/apps/base/home-system/qui/app/\"\n    - name: radarr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/radarr/app/\"\n          to: \"@artifact/apps/base/home-system/radarr/app/\"\n    - name: recyclarr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/recyclarr/app/\"\n          to: \"@artifact/apps/base/home-system/recyclarr/app/\"\n    - name: reflector\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/reflector/app/\"\n          to: \"@artifact/apps/base/kube-system/reflector/app/\"\n    - name: rook-ceph-cluster\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/rook-ceph/rook-ceph/cluster/\"\n          to: \"@artifact/apps/base/rook-ceph/rook-ceph/cluster/\"\n    - name: rook-ceph\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/rook-ceph/rook-ceph/app/\"\n          to: \"@artifact/apps/base/rook-ceph/rook-ceph/app/\"\n    - name: sabnzbd\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/sabnzbd/app/\"\n          to: \"@artifact/apps/base/home-system/sabnzbd/app/\"\n    - name: silence-operator\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/silence-operator/app/\"\n          to: \"@artifact/apps/base/observability/silence-operator/app/\"\n    - name: smtp-relay\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/smtp-relay/app/\"\n          to: \"@artifact/apps/base/home-system/smtp-relay/app/\"\n    - name: snapshot-controller\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/snapshot-controller/app/\"\n          to: \"@artifact/apps/base/kube-system/snapshot-controller/app/\"\n    - name: sonarr\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/sonarr/app/\"\n          to: \"@artifact/apps/base/home-system/sonarr/app/\"\n    - name: spegel\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/spegel/app/\"\n          to: \"@artifact/apps/base/kube-system/spegel/app/\"\n    - name: tautulli\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/tautulli/app/\"\n          to: \"@artifact/apps/base/home-system/tautulli/app/\"\n    - name: tetragon\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/kube-system/tetragon/app/\"\n          to: \"@artifact/apps/base/kube-system/tetragon/app/\"\n    - name: vcluster\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/development/vcluster/app/\"\n          to: \"@artifact/apps/base/development/vcluster/app/\"\n    - name: volsync-maintenance\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/volsync-system/volsync/maintenance/\"\n          to: \"@artifact/apps/base/volsync-system/volsync/maintenance/\"\n    - name: volsync\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/volsync-system/volsync/app/\"\n          to: \"@artifact/apps/base/volsync-system/volsync/app/\"\n    - name: vpa\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/observability/vpa/app/\"\n          to: \"@artifact/apps/base/observability/vpa/app/\"\n    - name: zigbee2mqtt\n      originRevision: \"@repo\"\n      copy:\n        - from: \"@repo/apps/base/home-system/zigbee2mqtt/app/\"\n          to: \"@artifact/apps/base/home-system/zigbee2mqtt/app/\"\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/artifact-generator/kustomization.yaml",
    "content": "---\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  - artifactgenerator.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/extras/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: flux-k8s-api-performance\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://raw.githubusercontent.com/controlplaneio-fluxcd/flux-operator/refs/heads/main/config/monitoring/dashboards/flux-k8s-api-performance.json\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: flux-performance\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://raw.githubusercontent.com/controlplaneio-fluxcd/flux-operator/refs/heads/main/config/monitoring/dashboards/flux-performance.json\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: flux-cluster\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://raw.githubusercontent.com/fluxcd/flux2-monitoring-example/refs/heads/main/monitoring/configs/dashboards/cluster.json\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: flux-control-plane\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://raw.githubusercontent.com/fluxcd/flux2-monitoring-example/refs/heads/main/monitoring/configs/dashboards/control-plane.json\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/extras/httproute.yaml",
    "content": "# Used to enable webhook-receivers https://toolkit.fluxcd.io/guides/webhook-receivers/\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: receiver\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'receiver.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: webhook-receiver\n          port: 80\n          weight: 100\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: flux\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'flux.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: flux-operator\n          port: 9080\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/extras/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - grafanadashboard.yaml\n  - httproute.yaml\n  - podmonitor.yaml\n  - prometheusrule.yaml\n  - receiver.yaml\n  - secret.enc.age.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/extras/podmonitor.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/podmonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PodMonitor\nmetadata:\n  name: flux-components\nspec:\n  namespaceSelector:\n    matchNames:\n      - flux-system\n  podMetricsEndpoints:\n    - honorLabels: true\n      port: http-prom\n  selector:\n    matchExpressions:\n      - key: app.kubernetes.io/component\n        operator: In\n        values:\n          - helm-controller\n          - source-controller\n          - kustomize-controller\n          - notification-controller\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/extras/prometheusrule.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/prometheusrule_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  name: flux-instance-rules\nspec:\n  groups:\n    - name: flux-instance.rules\n      rules:\n        - alert: FluxInstanceAbsent\n          expr: |-\n            absent(flux_instance_info{exported_namespace=\"flux-system\", name=\"flux\"})\n          for: 30m\n          annotations:\n            summary: >-\n              Flux instance metric is missing\n          labels:\n            severity: critical\n\n        - alert: FluxInstanceNotReady\n          expr: |-\n            flux_instance_info{exported_namespace=\"flux-system\", name=\"flux\", ready!=\"True\"}\n          for: 30m\n          annotations:\n            summary: >-\n              Flux instance {{ $labels.name }} is not ready\n          labels:\n            severity: critical\n\n        - alert: HelmReleaseReconciliationFailure\n          expr: |-\n            gotk_resource_info{customresource_kind=\"HelmRelease\", ready!=\"True\"} == 1\n          for: 1h\n          annotations:\n            summary: >-\n              HelmRelease {{ $labels.name }} in {{ $labels.exported_namespace }} is not ready\n          labels:\n            severity: warning\n\n        - alert: KustomizationReconciliationFailure\n          expr: |-\n            gotk_resource_info{customresource_kind=\"Kustomization\", ready!=\"True\"} == 1\n          for: 1h\n          annotations:\n            summary: >-\n              Kustomization {{ $labels.name }} in {{ $labels.exported_namespace }} is not ready\n          labels:\n            severity: warning\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/extras/receiver.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/notification.toolkit.fluxcd.io/receiver_v1.json\napiVersion: notification.toolkit.fluxcd.io/v1\nkind: Receiver\nmetadata:\n  name: k8s-gitops\nspec:\n  type: github\n  events:\n    - 'ping'\n    - 'push'\n  secretRef:\n    name: webhook-token\n  resources:\n    - apiVersion: source.toolkit.fluxcd.io/v1\n      kind: GitRepository\n      name: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/extras/secret.enc.age.yaml",
    "content": "apiVersion: v1\ndata:\n  token: ENC[AES256_GCM,data:O3HFn7k8QHDrI08N7Zm9ltdb227dGUYRi25XbqN9JVZ7Kk4Cv1fL1aWgfPulUzm3BT/s3y9xs6k=,iv:nUhnWKD2Ra4bp2NXU3jr46fulOHIQCkuA4HebiDWXSA=,tag:CNyRFkVfdqubkmlvyKgCHg==,type:str]\nkind: Secret\nmetadata:\n  name: webhook-token\n  namespace: flux-system\ntype: Opaque\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLVHAzTk5TZ0dSKytyK0JU\n        M0FORlFMcEV2bzhsYWhHaEpMVFcxYU5yZVFnCk5GVCsyZTd0aVpnalNKdmU5bVFj\n        ZVk4RnJIN3UzeWJpV1lVaTI0MW5Ia3MKLS0tIENuS2pLYU1DcVd2ZmQxL0d5RTFs\n        YUZBVHh5NXlDakxhYjZWd0Jnb2R6RGMKyajLM/s42+kIwhD3plA4HDSDpkR6+tGI\n        wJ4oDJNDBzbsxfXHB4Wf2feyTPuhptmSQ9+Wqk6RCID+7xX4b7GMAg==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:21:04Z\"\n  mac: ENC[AES256_GCM,data:CYZ7OY9wz6ahH1WLiv3g+hSlrpclDSUMCJTYZ55afXyLH+/e5/FNIKr3d6gd5wh5Rca5uRdSDrS7FE8j1Isnldya3ykCFEuL4iE1im2XshsGXl78q0CQYfIrhMY0s23POlbjyTWH1Z09JnPVfcTLddl2vaGt3azatOfpR7qVmZo=,iv:1X2T0lIBrObmSzCkFl/XL1zjA1CXyftSL3tyqz7o2i8=,tag:5tbJCIJiZEdCHkkd+6bzWQ==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/flux-instance/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: &app flux-instance-extras\n  namespace: flux-system\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  path: ./apps/base/flux-system/flux-instance/extras\n  prune: false\n  sourceRef:\n    kind: ExternalArtifact\n    name: flux-instance-extras\n    namespace: flux-system\n  targetNamespace: flux-system\n  timeout: 5m\n  wait: false\n  postBuild:\n    substituteFrom:\n      - kind: ConfigMap\n        name: cluster-config\n      - kind: Secret\n        name: cluster-secrets\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/git/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources: []\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/backstage-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: backstage-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://backstage.github.io/charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/crowdsec-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: crowdsec-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://crowdsecurity.github.io/helm-charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/democratic-csi-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: democratic-csi-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://democratic-csi.github.io/charts/\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/dex-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: dex-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.dexidp.io\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/fairwinds-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: fairwinds-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.fairwinds.com/stable\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/fluxcd-kustomize-mutating-webhook-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/refs/heads/main/helmrepository-source-v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: fluxcd-kustomize-mutating-webhook\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://xunholy.github.io/fluxcd-kustomize-mutating-webhook\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/gatekeeper-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: gatekeeper-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://open-policy-agent.github.io/gatekeeper/charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/harbor-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: harbor-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://helm.goharbor.io\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/ingress-nginx-chart.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: ingress-nginx-chart\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://kubernetes.github.io/ingress-nginx\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: flux-system\n\nresources:\n  - backstage-charts.yaml\n  - crowdsec-charts.yaml\n  - harbor-charts.yaml\n  - democratic-csi-charts.yaml\n  - dex-chart.yaml\n  - fairwinds-charts.yaml\n  - gatekeeper-charts.yaml\n  - ingress-nginx-chart.yaml\n  - loft-charts.yaml\n  - minecraft-server-charts.yaml\n  - ollama-charts.yaml\n  - open-webui-charts.yaml\n  - fluxcd-kustomize-mutating-webhook-chart.yaml\n  - openfeature-charts.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/loft-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: loft-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://charts.loft.sh\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/minecraft-server-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: minecraft-server-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://itzg.github.io/minecraft-server-charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/ollama-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: ollama-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://helm.otwld.com\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/open-webui-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: open-webui-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://open-webui.github.io/helm-charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/helm/openfeature-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: openfeature-charts\n  namespace: flux-system\nspec:\n  interval: 2h\n  url: https://open-feature.github.io/open-feature-operator/\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - git\n  - helm\n  - oci\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/oci/bjw-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: app-template\n  namespace: flux-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 4.6.2\n  url: oci://ghcr.io/bjw-s-labs/helm/app-template\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/oci/controlplaneio-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: controlplaneio-charts\n  namespace: flux-system\nspec:\n  type: oci\n  interval: 2h\n  url: oci://ghcr.io/controlplaneio-fluxcd/charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/oci/gha-runner-scale-set-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: gha-runner-scale-set-charts\n  namespace: flux-system\nspec:\n  type: oci\n  interval: 2h\n  url: oci://ghcr.io/actions/actions-runner-controller-charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/oci/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: flux-system\n\nresources:\n  - bjw-charts.yaml\n  - gha-runner-scale-set-charts.yaml\n  - controlplaneio-charts.yaml\n  - prometheus-community-charts.yaml\n  - xentra-charts.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/oci/prometheus-community-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: prometheus-community-charts\n  namespace: flux-system\nspec:\n  interval: 120m\n  type: oci\n  url: oci://ghcr.io/prometheus-community/charts\n"
  },
  {
    "path": "kubernetes/apps/base/flux-system/repositories/oci/xentra-charts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/helmrepository_v1beta2.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: HelmRepository\nmetadata:\n  name: xentra-charts\n  namespace: flux-system\nspec:\n  interval: 120m\n  type: oci\n  url: oci://ghcr.io/xentra-ai/charts\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/adminer/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: adminer\n  namespace: game-servers\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      app:\n        containers:\n          app:\n            image:\n              repository: adminer\n              tag: \"5\"\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              # Default server pre-filled in the login form so an admin\n              # only has to enter user + password.\n              ADMINER_DEFAULT_SERVER: cmangos-database.game-servers.svc.cluster.local\n              # No design preference; the dark theme is easier on the eyes\n              # when staring at item_template at 2am.\n              ADMINER_DESIGN: pepa-linha-dark\n            probes:\n              liveness: &probe\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /\n                    port: 8080\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness: *probe\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /\n                    port: 8080\n                  periodSeconds: 5\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 10m\n                memory: 32Mi\n              limits:\n                memory: 128Mi\n            securityContext:\n              allowPrivilegeEscalation: false\n              # adminer's entrypoint symlinks adminer.css into the\n              # working directory based on ADMINER_DESIGN, so the rootfs\n              # needs to be writable. Caps still dropped + non-root.\n              readOnlyRootFilesystem: false\n              capabilities:\n                drop: [\"ALL\"]\n    defaultPodOptions:\n      securityContext:\n        # adminer:5 image USER is \"adminer\" (UID 8 from adduser -u 8).\n        # Numeric so the kubelet can verify non-root.\n        runAsUser: 8\n        runAsGroup: 8\n        runAsNonRoot: true\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: app\n        ports:\n          http:\n            port: 8080\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/adminer/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: adminer\nspec:\n  parentRefs:\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'adminer.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: adminer\n          port: 8080\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/adminer/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/adminer/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: adminer\n  namespace: game-servers\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 10m\n  path: \"./apps/base/game-servers/adminer/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: ExternalArtifact\n    name: adminer\n    namespace: flux-system\n  dependsOn:\n    - name: cmangos\n      namespace: game-servers\n  targetNamespace: game-servers\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/dnsendpoint.yaml",
    "content": "---\napiVersion: externaldns.k8s.io/v1alpha1\nkind: DNSEndpoint\nmetadata:\n  name: azerothcore-wotlk\n  annotations:\n    external-dns.alpha.kubernetes.io/external: \"true\"\nspec:\n  endpoints:\n    - dnsName: \"wotlk.${CLUSTER_DOMAIN}\"\n      recordType: A\n      targets:\n        - \"${EXTERNAL_IP}\"\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: azerothcore\n  namespace: game-servers\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      database:\n        containers:\n          app:\n            image:\n              repository: mysql\n              tag: \"9.6\"\n            args:\n              - --skip-log-bin\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              MYSQL_ROOT_PASSWORD: password\n              MYSQL_DATABASE: acore_auth\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['mysqladmin', 'ping', '-h', 'localhost']\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['mysqladmin', 'ping', '-h', 'localhost']\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['mysqladmin', 'ping', '-h', 'localhost']\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 2Gi\n      authserver:\n        initContainers:\n          wait-db-ready:\n            image:\n              repository: mysql\n              tag: \"9.6\"\n            command: ['sh', '-c', 'until mysql -h azerothcore-database -u root -ppassword -e \"SELECT 1 FROM acore_auth.realmlist LIMIT 1\" 2>/dev/null; do echo \"Waiting for db-import to populate databases...\"; sleep 10; done']\n        containers:\n          app:\n            image:\n              repository: ghcr.io/xunholy/azerothcore-wotlk-authserver\n              tag: f9bcdac1895f78e50a63e8e93f09ce0d723cf938\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              AC_LOGIN_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_auth\"\n              AC_CLOSE_IDLE_CONNECTIONS: \"0\"\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 5\n                  timeoutSeconds: 3\n                  failureThreshold: 60\n            resources:\n              requests:\n                cpu: 10m\n                memory: 64Mi\n              limits:\n                memory: 256Mi\n      worldserver:\n        pod:\n          terminationGracePeriodSeconds: 960\n          # fsGroup makes the mounted cores PVC group-owned by acore (gid 1000)\n          # so the worldserver process can drop core files into it on crash.\n          # Without this, kubelet creates the mount point as root:root and the\n          # acore user can't write there.\n          securityContext:\n            fsGroup: 1000\n            fsGroupChangePolicy: OnRootMismatch\n        initContainers:\n          01-wait-db:\n            image:\n              repository: mysql\n              tag: \"9.6\"\n            command:\n              - sh\n              - -c\n              - |\n                until mysqladmin ping -h azerothcore-database -u root -ppassword --silent; do sleep 2; done\n                echo \"Creating databases...\"\n                mysql -h azerothcore-database -u root -ppassword -e \"\n                  CREATE DATABASE IF NOT EXISTS acore_auth;\n                  CREATE DATABASE IF NOT EXISTS acore_world;\n                  CREATE DATABASE IF NOT EXISTS acore_characters;\n                  CREATE DATABASE IF NOT EXISTS acore_playerbots;\n                \"\n                echo \"All databases ready.\"\n          02-db-import:\n            image:\n              repository: ghcr.io/xunholy/azerothcore-wotlk-db-import\n              tag: f9bcdac1895f78e50a63e8e93f09ce0d723cf938\n            env:\n              AC_LOGIN_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_auth\"\n              AC_WORLD_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_world\"\n              AC_CHARACTER_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_characters\"\n              AC_PLAYERBOTS_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_playerbots\"\n              AC_CLOSE_IDLE_CONNECTIONS: \"0\"\n              AC_UPDATES_ENABLE_DATABASES: \"7\"\n              AC_PLAYERBOTS_UPDATES_ENABLE_DATABASES: \"1\"\n              AC_PLAYERBOTS_DATABASE_WORKER_THREADS: \"1\"\n              AC_PLAYERBOTS_DATABASE_SYNCH_THREADS: \"1\"\n              AC_DATA_DIR: /azerothcore/env/dist/data\n          025-module-sql:\n            image:\n              repository: ghcr.io/xunholy/azerothcore-wotlk-db-import\n              tag: f9bcdac1895f78e50a63e8e93f09ce0d723cf938\n            command:\n              - /bin/bash\n              - -c\n              - |\n                import_sql() {\n                  local db=\"$1\" pattern=\"$2\"\n                  find /azerothcore/modules -path \"$pattern\" -name \"*.sql\" 2>/dev/null | sort | while read -r f; do\n                    echo \"  $(basename \"$f\") -> $db\"\n                    mysql -h azerothcore-database -u root -ppassword \"$db\" < \"$f\" 2>/dev/null || true\n                  done\n                }\n                echo \"=== Applying module SQL ===\"\n                echo \"World database:\"\n                import_sql acore_world \"*/data/sql/db-world/*\"\n                import_sql acore_world \"*/data/sql/world/base/*\"\n                echo \"Characters database:\"\n                import_sql acore_characters \"*/data/sql/db-characters/*\"\n                import_sql acore_characters \"*/data/sql/characters/base/*\"\n                echo \"Auth database:\"\n                import_sql acore_auth \"*/data/sql/db-auth/*\"\n                import_sql acore_auth \"*/data/sql/auth/base/*\"\n                echo \"Playerbots database:\"\n                import_sql acore_playerbots \"*/data/sql/playerbots/base/*\"\n                echo \"=== Module SQL complete ===\"\n          03-client-data:\n            image:\n              repository: acore/ac-wotlk-client-data\n              tag: master\n        containers:\n          app:\n            image:\n              repository: ghcr.io/xunholy/azerothcore-wotlk-worldserver\n              tag: f9bcdac1895f78e50a63e8e93f09ce0d723cf938\n            tty: true\n            stdin: true\n            # Override the image ENTRYPOINT so we can:\n            #   - enable core dumps (ulimit -c) and chdir into the cores PVC\n            #   - patch mod_ahbot.conf with our AHBot Account/GUID before the\n            #     worldserver reads it. (The AC_* env vars in this HR don't\n            #     translate to .conf — the upstream entrypoint has no env\n            #     substitution. Settings only stick when written to the conf\n            #     file directly. ConfigMap subPath at .../modules/<f> won't\n            #     work because k8s shadows the parent dir as root-owned and\n            #     hides the sibling .conf.dist files the wrapper needs.)\n            # The wrapper at /azerothcore/entrypoint.sh is no-clobber for\n            # files we wrote, so we replicate just its conf-materialization\n            # step, sed the override, then hand off.\n            command:\n              - /bin/bash\n              - -c\n              # Flux post-build substitution eats `${VAR}` tokens; escape any\n              # parameter-expansion / suffix-strip below as `$${VAR}` so bash\n              # sees them at runtime. Plain `$VAR` (no braces) is fine.\n              - |\n                set -euo pipefail\n                ulimit -c unlimited\n                mkdir -p /azerothcore/env/dist/cores\n                cd /azerothcore/env/dist/cores\n                ref=/azerothcore/env/ref/etc/modules\n                dist=/azerothcore/env/dist/etc/modules\n                if [ -d \"$ref\" ]; then\n                  mkdir -p \"$dist\"\n                  for src in \"$ref\"/*.conf.dist; do\n                    [ -f \"$src\" ] || continue\n                    target=\"$dist/$(basename \"$${src%.dist}\")\"\n                    [ -f \"$target\" ] || cp \"$src\" \"$target\"\n                  done\n                fi\n                if [ -f \"$dist/mod_ahbot.conf\" ]; then\n                  # AHBot owner + volume tuning. account 199 = AHBOT,\n                  # guid 1006 = Auctioneer. Profession + vendor trade goods\n                  # turned on so the world has crafted gear, bolts of cloth,\n                  # potions etc. on top of the loot-only seed. Duplicates=3\n                  # gives popular items multiple listings; ItemsPerCycle=400\n                  # roughly doubles fill+rotation rate.\n                  sed -i \\\n                    -e 's|^AuctionHouseBot\\.EnableSeller *=.*|AuctionHouseBot.EnableSeller = 1|' \\\n                    -e 's|^AuctionHouseBot\\.EnableBuyer *=.*|AuctionHouseBot.EnableBuyer = 1|' \\\n                    -e 's|^AuctionHouseBot\\.Account *=.*|AuctionHouseBot.Account = 199|' \\\n                    -e 's|^AuctionHouseBot\\.GUID *=.*|AuctionHouseBot.GUID = 1006|' \\\n                    -e 's|^AuctionHouseBot\\.UseMarketPriceForSeller *=.*|AuctionHouseBot.UseMarketPriceForSeller = 1|' \\\n                    -e 's|^AuctionHouseBot\\.ItemsPerCycle *=.*|AuctionHouseBot.ItemsPerCycle = 400|' \\\n                    -e 's|^AuctionHouseBot\\.ProfessionItems *=.*|AuctionHouseBot.ProfessionItems = 1|' \\\n                    -e 's|^AuctionHouseBot\\.VendorTradeGoods *=.*|AuctionHouseBot.VendorTradeGoods = 1|' \\\n                    -e 's|^AuctionHouseBot\\.DuplicatesCount *=.*|AuctionHouseBot.DuplicatesCount = 3|' \\\n                    \"$dist/mod_ahbot.conf\"\n                fi\n                if [ -f \"$dist/playerbots.conf\" ]; then\n                  # Aliveness pass: more bots, faster RPG-state transitions,\n                  # busier world/general/trade chat, more loot/kill broadcast\n                  # spam. Explicitly NOT touched: RandomBotInvitePlayer (0),\n                  # InviteChat (0), RandomBotGuildNearby (0) — real players\n                  # should not be DM'd, group-invited, or auto-recruited into\n                  # bot guilds.\n                  sed -i \\\n                    -e 's|^AiPlayerbot\\.MinRandomBots *=.*|AiPlayerbot.MinRandomBots = 800|' \\\n                    -e 's|^AiPlayerbot\\.MaxRandomBots *=.*|AiPlayerbot.MaxRandomBots = 800|' \\\n                    -e 's|^AiPlayerbot\\.RpgDelay *=.*|AiPlayerbot.RpgDelay = 5000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastToWorldGlobalChance *=.*|AiPlayerbot.BroadcastToWorldGlobalChance = 90000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastToGeneralGlobalChance *=.*|AiPlayerbot.BroadcastToGeneralGlobalChance = 90000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastToTradeGlobalChance *=.*|AiPlayerbot.BroadcastToTradeGlobalChance = 90000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastToLFGGlobalChance *=.*|AiPlayerbot.BroadcastToLFGGlobalChance = 60000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastChanceLootingItemRare *=.*|AiPlayerbot.BroadcastChanceLootingItemRare = 40000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastChanceLootingItemEpic *=.*|AiPlayerbot.BroadcastChanceLootingItemEpic = 60000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastChanceKillRare *=.*|AiPlayerbot.BroadcastChanceKillRare = 20000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastChanceKillRareelite *=.*|AiPlayerbot.BroadcastChanceKillRareelite = 6000|' \\\n                    -e 's|^AiPlayerbot\\.BroadcastChanceKillWorldboss *=.*|AiPlayerbot.BroadcastChanceKillWorldboss = 40000|' \\\n                    \"$dist/playerbots.conf\"\n                fi\n                exec /azerothcore/entrypoint.sh /azerothcore/env/dist/bin/worldserver\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              # Enable interactive console so preStop can inject commands via FIFO\n              AC_DISABLE_INTERACTIVE: \"0\"\n              # Database connections\n              AC_LOGIN_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_auth\"\n              AC_WORLD_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_world\"\n              AC_CHARACTER_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_characters\"\n              AC_PLAYERBOTS_DATABASE_INFO: \"azerothcore-database;3306;root;password;acore_playerbots\"\n              AC_PLAYERBOTS_UPDATES_ENABLE_DATABASES: \"0\"\n              AC_PLAYERBOTS_DATABASE_WORKER_THREADS: \"1\"\n              AC_PLAYERBOTS_DATABASE_SYNCH_THREADS: \"1\"\n              AC_CLOSE_IDLE_CONNECTIONS: \"0\"\n              AC_UPDATES_ENABLE_DATABASES: \"7\"\n              AC_DATA_DIR: /azerothcore/env/dist/data\n              AC_LOGS_DIR: /azerothcore/env/dist/logs\n              # Server identity\n              AC_GAME_TYPE: \"0\"\n              AC_REALM_ZONE: \"8\"\n              AC_WORLD_SERVER_PORT: \"8085\"\n              AC_PLAYER_LIMIT: \"100\"\n              AC_MOTD: \"Welcome to Emberstone | Progression Realm | Earn Outland and Northrend through raid clears\"\n              # SOAP remote admin\n              AC_SOAP_ENABLED: \"1\"\n              AC_SOAP_IP: \"0.0.0.0\"\n              AC_SOAP_PORT: \"7878\"\n              # -- 3x rates: faster than vanilla but tiers still feel earned --\n              AC_RATE_XP_KILL: \"3\"\n              AC_RATE_XP_QUEST: \"3\"\n              AC_RATE_XP_EXPLORE: \"3\"\n              AC_RATE_XP_BG_KILL: \"3\"\n              AC_RATE_XP_PET: \"3\"\n              # -- Drops --\n              AC_RATE_DROP_ITEM_POOR: \"3\"\n              AC_RATE_DROP_ITEM_NORMAL: \"3\"\n              AC_RATE_DROP_ITEM_UNCOMMON: \"3\"\n              AC_RATE_DROP_ITEM_RARE: \"3\"\n              AC_RATE_DROP_ITEM_EPIC: \"2\"\n              AC_RATE_DROP_ITEM_LEGENDARY: \"1\"\n              AC_RATE_DROP_ITEM_QUEST: \"3\"\n              AC_RATE_DROP_MONEY: \"3\"\n              # -- Reputation and honor --\n              AC_RATE_REPUTATION_GAIN: \"3\"\n              AC_RATE_HONOR: \"3\"\n              AC_RATE_ARENA_POINTS: \"3\"\n              # -- Profession skill-ups --\n              AC_SKILL_GAIN_CRAFTING: \"3\"\n              AC_SKILL_GAIN_GATHERING: \"3\"\n              AC_SKILL_GAIN_WEAPON: \"3\"\n              AC_SKILL_GAIN_DEFENSE: \"3\"\n              AC_RATE_SKILL_DISCOVERY: \"3\"\n              # -- Quality of life (kept; QoL that doesn't fight IP) --\n              AC_RATE_REST_INGAME: \"3\"\n              AC_RATE_REST_OFFLINE_IN_TAVERN_OR_CITY: \"3\"\n              AC_DEATH_SICKNESS_LEVEL: \"1\"\n              AC_SKIP_CINEMATICS: \"1\"\n              AC_PLAYER_SAVE_INTERVAL: \"60000\"\n              # NOTE: removed ALL_FLIGHT_PATHS, INSTANT_FLIGHT_PATHS, MAIL_DELIVERY_DELAY=0,\n              # START_PLAYER_MONEY=100000 — these undermine IP's \"the world is bigger again\" design.\n              # -- Health and mana regen --\n              AC_RATE_HEALTH: \"3\"\n              AC_RATE_MANA: \"3\"\n              AC_RATE_POWER_RAGE_INCOME: \"3\"\n              AC_RATE_POWER_RAGE_LOSS: \"1\"\n              AC_RATE_POWER_ENERGY: \"3\"\n              AC_RATE_POWER_FOCUS: \"3\"\n              # -- Ghost run speed for less death penalty --\n              AC_GHOST_RUN_SPEED_WORLD: \"1.5\"\n              AC_GHOST_RUN_SPEED_BG: \"1.5\"\n              # ==============================================\n              # Module: mod-playerbots (AI player bots)\n              # ==============================================\n              AC_AIPLAYERBOT_ENABLED: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTAUTOCREATE: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTAUTOLOGIN: \"1\"\n              AC_AIPLAYERBOT_LOGINATEACHPLAYERLEVELBOT: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTACCOUNTPREFIX: \"rndbot\"\n              AC_AIPLAYERBOT_RANDOMBOTACCOUNTCOUNT: \"200\"\n              AC_AIPLAYERBOT_MINRANDOMBOTS: \"500\"\n              AC_AIPLAYERBOT_MAXRANDOMBOTS: \"1000\"\n              AC_AIPLAYERBOT_RANDOMBOTMINLEVEL: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTMAXLEVEL: \"80\"\n              AC_AIPLAYERBOT_RANDOMBOTMAPS: \"0,1,530,571\"\n              AC_AIPLAYERBOT_AUTODOQUESTS: \"1\"\n              AC_AIPLAYERBOT_AUTOPICKREWARD: \"yes\"\n              AC_AIPLAYERBOT_AUTOEQUIPUPGRADELOOT: \"1\"\n              AC_AIPLAYERBOT_AUTOLEARNTRAINERSPELLS: \"1\"\n              AC_AIPLAYERBOT_AUTOLEARNQUESTSPELLS: \"1\"\n              AC_AIPLAYERBOT_RANDOMGEARUPGRADEENABLED: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTTELEPORTNEARPLAYER: \"1\"\n              AC_AIPLAYERBOT_SYNCQUESTWITHPLAYER: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTJOINBG: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTAUTOJOINBG: \"1\"\n              AC_AIPLAYERBOT_RANDOMBOTGROUPNEARBY: \"1\"\n              AC_AIPLAYERBOT_SYNCLEVELWITHPLAYERS: \"1\"\n              AC_AIPLAYERBOT_SYNCLEVELMAXABOVE: \"2\"\n              AC_AIPLAYERBOT_AUTOPICKTALENTS: \"full\"\n              AC_AIPLAYERBOT_AUTOTRAINSPELLS: \"free\"\n              # ==============================================\n              # Module: mod-autobalance (instance scaling)\n              # Disabled: IP wants raids to require a raid; autobalance with MINPLAYERS=1\n              # would let you solo MC and defeat the gating experience.\n              # ==============================================\n              AC_AUTOBALANCE_ENABLE: \"0\"\n              # ==============================================\n              # Module: mod-transmog (transmogrification)\n              # ==============================================\n              AC_TRANSMOGRIFICATION_ENABLE: \"1\"\n              AC_TRANSMOGRIFICATION_SETNSETHINGS_ENABLE: \"1\"\n              # ==============================================\n              # Module: mod-ah-bot (auction house bot)\n              # ==============================================\n              AC_AUCTIONHOUSEBOT_ENABLESELLER: \"1\"\n              AC_AUCTIONHOUSEBOT_ENABLEBUYER: \"1\"\n              # ==============================================\n              # Module: mod-cfbg (cross-faction battlegrounds)\n              # ==============================================\n              AC_CFBG_ENABLE: \"1\"\n              # ==============================================\n              # Module: mod-solo-lfg (solo dungeon finder)\n              # Disabled: trivializes early-game dungeons that IP wants to feel earned.\n              # Playerbots fill the dungeon-group role instead.\n              # ==============================================\n              AC_SOLOLFG_ENABLE: \"0\"\n              # ==============================================\n              # IP requires these for stat-scaling to take effect. The module's\n              # SimpleConfigOverride is supposed to force them at runtime but\n              # observation showed the on-disk worldserver.conf still has the\n              # AC defaults, so set them explicitly to be safe.\n              # ==============================================\n              AC_ENABLE_PLAYER_SETTINGS: \"1\"\n              AC_DBC_ENFORCE_ITEM_ATTRIBUTES: \"0\"\n              # ==============================================\n              # Module: mod-individual-progression (per-character expansion gating)\n              # Power/healing scalars at IP author's recommended values for\n              # \"Vanilla feels like Vanilla, TBC feels like TBC\" — without these,\n              # gating works but content does WotLK-tier damage values.\n              # Other defaults are sane (StartingProgression=0 -> achievements\n              # scanned on login, ExcludedAccountsRegex='^RNDBOT.*' -> auto-excludes\n              # our playerbots).\n              # ==============================================\n              AC_INDIVIDUAL_PROGRESSION_ENABLE: \"1\"\n              AC_INDIVIDUAL_PROGRESSION_VANILLA_POWER_ADJUSTMENT: \"0.5\"\n              AC_INDIVIDUAL_PROGRESSION_VANILLA_HEALING_ADJUSTMENT: \"0.5\"\n              AC_INDIVIDUAL_PROGRESSION_TBCPOWER_ADJUSTMENT: \"0.6\"\n              AC_INDIVIDUAL_PROGRESSION_TBCHEALING_ADJUSTMENT: \"0.6\"\n            lifecycle:\n              preStop:\n                exec:\n                  command:\n                    - /bin/sh\n                    - -c\n                    - |\n                      echo \"server restart 900\" > /tmp/worldserver-stdin\n                      sleep 910\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 180\n            resources:\n              requests:\n                cpu: \"2\"\n                memory: 4Gi\n              limits:\n                memory: 12Gi\n          # Prune /azerothcore/env/dist/cores so a runaway crash loop can't\n          # fill the 40Gi PVC. Keeps the 2 newest non-zero cores by mtime\n          # and deletes the rest every 10 min. Mirrors the cmangos pattern.\n          cores-pruner:\n            image:\n              repository: busybox\n              tag: latest\n            command:\n              - /bin/sh\n              - -c\n              - |\n                while true; do\n                  if cd /azerothcore/env/dist/cores 2>/dev/null; then\n                    find . -maxdepth 1 -name 'core*' -size 0 -delete 2>/dev/null\n                    # shellcheck disable=SC2012\n                    ls -1t core* 2>/dev/null | tail -n +3 | xargs -r rm -f --\n                  fi\n                  sleep 600\n                done\n            resources:\n              requests:\n                cpu: 5m\n                memory: 8Mi\n              limits:\n                memory: 32Mi\n            securityContext:\n              runAsNonRoot: false\n              readOnlyRootFilesystem: true\n              allowPrivilegeEscalation: false\n              capabilities:\n                drop: [\"ALL\"]\n    service:\n      database:\n        controller: database\n        ports:\n          mysql:\n            port: 3306\n      auth:\n        controller: authserver\n        ports:\n          auth:\n            port: 3724\n      world:\n        controller: worldserver\n        ports:\n          world:\n            port: 8085\n      soap:\n        controller: worldserver\n        ports:\n          soap:\n            port: 7878\n    persistence:\n      database:\n        existingClaim: azerothcore-database\n        advancedMounts:\n          database:\n            app:\n              - path: /var/lib/mysql\n      client-data:\n        existingClaim: azerothcore-client-data\n        advancedMounts:\n          worldserver:\n            02-db-import:\n              - path: /azerothcore/env/dist/data\n            03-client-data:\n              - path: /azerothcore/env/dist/data\n            app:\n              - path: /azerothcore/env/dist/data\n                readOnly: true\n      worldserver-logs:\n        type: emptyDir\n        advancedMounts:\n          worldserver:\n            app:\n              - path: /azerothcore/env/dist/logs\n      authserver-logs:\n        type: emptyDir\n        advancedMounts:\n          authserver:\n            app:\n              - path: /azerothcore/env/dist/logs\n      cores:\n        existingClaim: azerothcore-cores\n        advancedMounts:\n          worldserver:\n            app:\n              - path: /azerothcore/env/dist/cores\n            cores-pruner:\n              - path: /azerothcore/env/dist/cores\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc-database.yaml\n  - pvc-client-data.yaml\n  - pvc-cores.yaml\n  - tcproutes.yaml\n  - dnsendpoint.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n  - realm-config-job.yaml\n\n# Hash-suffixed CM. realmlist.sql edits change the suffix, which changes\n# the Job's volume reference, which (with kustomize.toolkit.fluxcd.io/force)\n# triggers a Job re-run. No more manual resource-name bumps.\n# NOTE: namespace must match the Job's namespace or kustomize won't\n# auto-rewrite references.\nconfigMapGenerator:\n  - name: azerothcore-realmlist-sql\n    namespace: game-servers\n    files:\n      - realmlist.sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/pvc-client-data.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: azerothcore-client-data\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/pvc-cores.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: azerothcore-cores\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 40Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/pvc-database.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: azerothcore-database\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/realm-config-job.yaml",
    "content": "---\n# Applies realmlist.sql against the auth DB. ConfigMap is hash-suffixed by\n# kustomize's configMapGenerator (see kustomization.yaml), so SQL edits\n# produce a new CM name, which forces the Job's spec to change. The Flux\n# force annotation lets kustomize-controller delete-and-recreate the\n# (immutable) Job when that happens.\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: azerothcore-realm-config\n  namespace: game-servers\n  annotations:\n    kustomize.toolkit.fluxcd.io/force: Enabled\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z azerothcore-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mysql:9.6\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying realm config ===\"\n              mysql -h azerothcore-database -P 3306 -u root -ppassword acore_auth < /sql/realmlist.sql\n              echo \"=== Realm config applied ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: azerothcore-realmlist-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/realmlist.sql",
    "content": "-- Realm identity for the auth DB. Edited inline by humans; consumed by\n-- realm-config-job.yaml via a hash-suffixed ConfigMap. Changes here\n-- trigger automatic Job re-runs (via the kustomize.toolkit.fluxcd.io/force\n-- annotation on the Job).\nUPDATE realmlist\nSET name = 'Emberstone',\n    address = '${EXTERNAL_IP}',\n    port = 3726,\n    gamebuild = 12340\nWHERE id = 1;\nSELECT id, name, address, port, gamebuild FROM realmlist WHERE id = 1;\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: azerothcore-database\nspec:\n  sourcePVC: azerothcore-database\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: azerothcore-database-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/resources/Dockerfile",
    "content": "# =============================================================================\n# AzerothCore WotLK 3.3.5a — Custom Build with Tier 1 Modules\n# Built from the mod-playerbots fork (requires core patches for bot support)\n#\n# Targets: worldserver, authserver, db-import\n# =============================================================================\n\n# -----------------------------------------------------------------------------\n# Stage 1: Clone sources and modules\n# -----------------------------------------------------------------------------\nFROM ubuntu:22.04 AS source\n\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    git ca-certificates \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Pinned SHAs for reproducible builds. Bump these when you want newer code;\n# leaving them on a moving branch is how silent regressions arrive.\nARG ACORE_SHA1=\"d115eb658606567de6892aa48950281117767130\"           # mod-playerbots/azerothcore-wotlk Playerbot branch\nARG MOD_PLAYERBOTS_SHA1=\"a4d2c83d85572a7c4f5bd4b4104187624c8337e3\"\nARG MOD_AUTOBALANCE_SHA1=\"73d4ad3c379fbfc35c63b5b9b44fba1f7d9e213d\"\nARG MOD_TRANSMOG_SHA1=\"f07686bf6a86412ba31502522bdc141266b8647d\"\nARG MOD_AHBOT_SHA1=\"a680cc1c98290713e9b3d3289544af78e5186dc1\"\nARG MOD_AOELOOT_SHA1=\"2ddf6ff75bdbfee3c81f2c149a07126f1d0bf200\"\nARG MOD_LEARNSPELLS_SHA1=\"016b92d520f343d074ffd5d46016a94f4a3a6ebd\"\nARG MOD_SOLOLFG_SHA1=\"3821fe1d108ade8d2b7ad6611e41154e05864c65\"\nARG MOD_CFBG_SHA1=\"d63ba2b844e0c3cd421d07aa8b009927425b21cd\"\nARG MOD_INDIVIDUALPROGRESSION_SHA1=\"4119ca0120e5b535b4718f6dd0a4d6030e28e1f8\"\n\n# Shallow-fetch a specific SHA: init -> remote add -> fetch --depth 1 <sha> -> checkout.\n# Avoids cloning full history while still giving us reproducible pins.\n# shellcheck disable=SC2086\nRUN set -eux; \\\n    fetch_sha() { \\\n    local url=\"$1\" sha=\"$2\" dest=\"$3\"; \\\n    mkdir -p \"$dest\"; \\\n    git -C \"$dest\" init -q; \\\n    git -C \"$dest\" remote add origin \"$url\"; \\\n    git -C \"$dest\" fetch --depth 1 -q origin \"$sha\"; \\\n    git -C \"$dest\" checkout -q FETCH_HEAD; \\\n    }; \\\n    fetch_sha https://github.com/mod-playerbots/azerothcore-wotlk.git           \"${ACORE_SHA1}\"                   /azerothcore; \\\n    fetch_sha https://github.com/mod-playerbots/mod-playerbots.git              \"${MOD_PLAYERBOTS_SHA1}\"          /azerothcore/modules/mod-playerbots; \\\n    fetch_sha https://github.com/azerothcore/mod-autobalance.git                \"${MOD_AUTOBALANCE_SHA1}\"         /azerothcore/modules/mod-autobalance; \\\n    fetch_sha https://github.com/azerothcore/mod-transmog.git                   \"${MOD_TRANSMOG_SHA1}\"            /azerothcore/modules/mod-transmog; \\\n    fetch_sha https://github.com/azerothcore/mod-ah-bot.git                     \"${MOD_AHBOT_SHA1}\"               /azerothcore/modules/mod-ah-bot; \\\n    fetch_sha https://github.com/azerothcore/mod-aoe-loot.git                   \"${MOD_AOELOOT_SHA1}\"             /azerothcore/modules/mod-aoe-loot; \\\n    fetch_sha https://github.com/azerothcore/mod-learn-spells.git               \"${MOD_LEARNSPELLS_SHA1}\"         /azerothcore/modules/mod-learn-spells; \\\n    fetch_sha https://github.com/azerothcore/mod-solo-lfg.git                   \"${MOD_SOLOLFG_SHA1}\"             /azerothcore/modules/mod-solo-lfg; \\\n    fetch_sha https://github.com/azerothcore/mod-cfbg.git                       \"${MOD_CFBG_SHA1}\"                /azerothcore/modules/mod-cfbg; \\\n    fetch_sha https://github.com/ZhengPeiRu21/mod-individual-progression.git    \"${MOD_INDIVIDUALPROGRESSION_SHA1}\" /azerothcore/modules/mod-individual-progression\n\n# -----------------------------------------------------------------------------\n# Stage 2: Compile\n# -----------------------------------------------------------------------------\nFROM ubuntu:22.04 AS build\n\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    build-essential ccache libtool cmake-data make cmake clang \\\n    git lsb-base curl unzip default-mysql-client openssl \\\n    default-libmysqlclient-dev libboost-all-dev libssl-dev libmysql++-dev \\\n    libreadline-dev zlib1g-dev libbz2-dev libncurses5-dev \\\n    && rm -rf /var/lib/apt/lists/*\n\nCOPY --from=source /azerothcore /azerothcore\nWORKDIR /azerothcore/build\n\nARG CTYPE=RelWithDebInfo\nARG THREADS=2\n\nRUN cmake /azerothcore \\\n    -DCMAKE_INSTALL_PREFIX=\"/azerothcore/env/dist\" \\\n    -DAPPS_BUILD=\"all\" \\\n    -DTOOLS_BUILD=\"all\" \\\n    -DSCRIPTS=\"static\" \\\n    -DMODULES=\"static\" \\\n    -DWITH_WARNINGS=\"OFF\" \\\n    -DCMAKE_BUILD_TYPE=\"${CTYPE}\" \\\n    -DCMAKE_CXX_COMPILER=\"clang++\" \\\n    -DCMAKE_C_COMPILER=\"clang\" \\\n    -DCMAKE_CXX_COMPILER_LAUNCHER=\"ccache\" \\\n    -DCMAKE_C_COMPILER_LAUNCHER=\"ccache\" \\\n    -DBoost_USE_STATIC_LIBS=\"ON\"\n\nRUN cmake --build . --config \"${CTYPE}\" -j \"${THREADS}\"\nRUN cmake --install . --config \"${CTYPE}\"\n\n# -----------------------------------------------------------------------------\n# Stage 3: Runtime base (shared by all server images)\n# -----------------------------------------------------------------------------\nFROM ubuntu:22.04 AS runtime\n\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    libmysqlclient21 libreadline8 gettext-base default-mysql-client \\\n    && rm -rf /var/lib/apt/lists/*\n\nRUN groupadd -g 1000 acore \\\n    && useradd -m -u 1000 -g acore acore\n\nCOPY --from=source /azerothcore/apps/docker/entrypoint.sh /azerothcore/entrypoint-upstream.sh\nCOPY fifo-wrapper.sh /azerothcore/entrypoint.sh\nRUN chmod +x /azerothcore/entrypoint-upstream.sh /azerothcore/entrypoint.sh\n\n# Reference configs (entrypoint copies to dist/etc on first run if not present)\nCOPY --from=build /azerothcore/env/dist/etc /azerothcore/env/ref/etc\n\nRUN mkdir -p /azerothcore/env/dist/etc /azerothcore/env/dist/logs /azerothcore/env/dist/data \\\n    && chown -R acore:acore /azerothcore\n\nENV CONF_DIR=/azerothcore/env/dist/etc \\\n    LOGS_DIR=/azerothcore/env/dist/logs \\\n    AC_FORCE_CREATE_DB=1 \\\n    AC_CLOSE_IDLE_CONNECTIONS=0 \\\n    AC_DISABLE_INTERACTIVE=1\n\nUSER acore\nENTRYPOINT [\"/azerothcore/entrypoint.sh\"]\n\n# -----------------------------------------------------------------------------\n# Stage 4: Auth server\n# -----------------------------------------------------------------------------\nFROM runtime AS authserver\nCOPY --from=build --chown=acore:acore /azerothcore/env/dist/bin/authserver /azerothcore/env/dist/bin/\nENV ACORE_COMPONENT=authserver\nEXPOSE 3724\nCMD [\"/azerothcore/env/dist/bin/authserver\"]\n\n# -----------------------------------------------------------------------------\n# Stage 5: World server\n# -----------------------------------------------------------------------------\nFROM runtime AS worldserver\nCOPY --from=build --chown=acore:acore /azerothcore/env/dist/bin/worldserver /azerothcore/env/dist/bin/\nENV ACORE_COMPONENT=worldserver\nEXPOSE 8085 7878\nCMD [\"/azerothcore/env/dist/bin/worldserver\"]\n\n# -----------------------------------------------------------------------------\n# Stage 6: DB import (schema + data + module SQL)\n# -----------------------------------------------------------------------------\nFROM runtime AS db-import\nCOPY --from=build --chown=acore:acore /azerothcore/env/dist/bin/dbimport /azerothcore/env/dist/bin/\nCOPY --from=source --chown=acore:acore /azerothcore/data /azerothcore/data\nCOPY --from=source --chown=acore:acore /azerothcore/modules /azerothcore/modules\nENV ACORE_COMPONENT=dbimport \\\n    AC_UPDATES_ENABLE_DATABASES=0\nCMD [\"/azerothcore/env/dist/bin/dbimport\"]\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/resources/fifo-wrapper.sh",
    "content": "#!/usr/bin/env bash\n# Wraps the upstream AzerothCore entrypoint to expose a named pipe at\n# /tmp/worldserver-stdin for the worldserver component. Lets preStop hooks\n# inject console commands like \"server restart 900\" for graceful,\n# player-notified shutdowns. Non-worldserver components are unaffected.\nset -euo pipefail\n\n# AC's upstream entrypoint runs `cp -rnv ref/etc/* dist/etc/` and then copies\n# the COMPONENT's .conf.dist to .conf — but only for the main component,\n# never for modules. Module configs end up as dist/etc/modules/*.conf.dist\n# with no .conf companion, so the loader falls back to defaults and emits\n# ~100 \"Missing property\" warnings per startup.\n#\n# Fix: pre-populate dist/etc/modules/*.conf from ref/etc/modules/*.conf.dist\n# BEFORE the upstream entrypoint runs. Upstream's `cp -rnv` is no-clobber,\n# so our pre-created .conf files survive.\nnormalize_module_confs() {\n    local ref_modules=/azerothcore/env/ref/etc/modules\n    local dist_modules=/azerothcore/env/dist/etc/modules\n    [ -d \"$ref_modules\" ] || return 0\n    mkdir -p \"$dist_modules\"\n    local src target\n    for src in \"$ref_modules\"/*.conf.dist; do\n        [ -f \"$src\" ] || continue\n        target=\"$dist_modules/$(basename \"${src%.dist}\")\"\n        [ -f \"$target\" ] || cp \"$src\" \"$target\"\n    done\n}\n\nnormalize_module_confs\n\nif [[ \"${ACORE_COMPONENT:-}\" == \"worldserver\" ]]; then\n    FIFO=/tmp/worldserver-stdin\n    rm -f \"$FIFO\"\n    mkfifo \"$FIFO\"\n    chmod 666 \"$FIFO\"\n    # Keep a writer attached so the server never sees EOF when a one-shot\n    # writer (preStop's echo) closes.\n    ( sleep infinity > \"$FIFO\" ) &\n    exec /azerothcore/entrypoint-upstream.sh \"$@\" < \"$FIFO\"\nelse\n    exec /azerothcore/entrypoint-upstream.sh \"$@\"\nfi\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/tcproutes.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: azerothcore-auth\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: azerothcore-auth\n  rules:\n    - backendRefs:\n        - name: azerothcore-auth\n          port: 3724\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: azerothcore-world\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: azerothcore-world\n  rules:\n    - backendRefs:\n        - name: azerothcore-world\n          port: 8085\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: azerothcore-database-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: azerothcore-database-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/azerothcore/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: azerothcore\n  namespace: game-servers\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 10m\n  path: \"./apps/base/game-servers/azerothcore/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: ExternalArtifact\n    name: azerothcore\n    namespace: flux-system\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: game-servers\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/README.md",
    "content": "# CMaNGOS Classic - Emberstone (1.12.1)\n\nA Vanilla WoW private server running CMaNGOS Classic on Kubernetes, with AI playerbots, hardcore mode, auction house bot, and a level 19 twink vendor system.\n\n## Architecture\n\nThe deployment consists of three controllers:\n\n| Controller | Image | Ports | Description |\n|---|---|---|---|\n| `database` | `mariadb:12.2` | 3306 | MariaDB storing all game databases |\n| `realmd` | `ghcr.io/xunholy/cmangos-classic` | 3724 | Authentication/realm server |\n| `mangosd` | `ghcr.io/xunholy/cmangos-classic` | 8085, 7878 (SOAP) | World server |\n\nThe container image is built from a [custom fork](https://github.com/flekz-games/mangos-classic) (`modules` branch) with the following compiled modules:\n\n- **PlayerBots** - AI bots that auto-create, level, do quests, and join battlegrounds\n- **AHBot** - Automated auction house population\n- **Hardcore** - Permadeath challenge system via [cmangos-hardcore](https://github.com/flekz-games/cmangos-hardcore)\n- **TwinkMaster** - Level 19 twink vendor/XP lock via [cmangos-twinkmaster](https://github.com/xunholy/cmangos-twinkmaster)\n\n## Server Configuration\n\nConfiguration files are managed as ConfigMaps mounted into the containers:\n\n| ConfigMap | Mount Path | Purpose |\n|---|---|---|\n| `mangosd.conf` | `/opt/mangos/conf/mangosd.conf` | World server settings (XP rates, player limits, etc.) |\n| `realmd.conf` | `/opt/mangos/conf/realmd.conf` | Auth server settings |\n| `aiplayerbot.conf` | `/opt/mangos/conf/aiplayerbot.conf` | Bot count, behavior, leveling |\n| `ahbot.conf` | `/opt/mangos/conf/ahbot.conf` | Auction house bot settings |\n| `hardcore.conf` | `/opt/mangos/etc/hardcore.conf` | Hardcore challenge rules |\n| `twinkmaster.conf` | `/opt/mangos/conf/twinkmaster.conf` | Twink vendor settings |\n\n### Key Server Settings\n\n- **XP Rate**: 3x (kill, quest, explore)\n- **Drop Rate**: 3x normal/uncommon, 2x rare, 1x epic\n- **Player Limit**: 100\n- **Cross-Faction**: Groups, guilds, chat, and channels all enabled\n- **Starting Gold**: 1g\n- **PlayerBots**: 1500-2000 bots, levels 1-60, auto-questing enabled\n- **Hardcore**: Permadeath enabled, graves spawn at death location, revive disabled\n\n## Managing Users\n\nAccounts are managed via the mangosd server console. Attach to the running pod:\n\n```bash\nkubectl attach -it -n game-servers deploy/cmangos-mangosd -c app\n```\n\n### Creating an Account\n\nIn the mangos console:\n\n```\naccount create <username> <password>\n```\n\n### Granting GM Privileges\n\n```\naccount set gmlevel <username> 3\n```\n\nTo detach from the console, press `Ctrl+P` then `Ctrl+Q`.\n\n## Account Registration\n\nA web-based registration page is available at `https://emberstone.owncloud.ai`. Players can create accounts without needing console access. The portal is deployed by the `emberstone-portal` app and serves both cmangos and azerothcore realms.\n\n## Connecting\n\n### Requirements\n\n- World of Warcraft **1.12.1** client (patch 5875)\n- An account on the server\n\n### Client Setup\n\n1. Edit `WoW/Data/enUS/realmlist.wtf` (or `enGB`):\n   ```\n   set realmlist wow.owncloud.ai\n   ```\n2. Launch WoW and log in\n\n## Networking\n\nExternal access is provided via Gateway API TCPRoutes through an Envoy gateway:\n\n- **Auth** (port 3724): `cmangos-auth` TCPRoute\n- **World** (port 8085): `cmangos-world` TCPRoute\n- **DNS**: `wow.owncloud.ai` pointed to the external IP via DNSEndpoint\n\n## Storage\n\n- **Database PVC** (`cmangos-database`): MariaDB data at `/var/lib/mysql`\n- **Data PVC** (`cmangos-data`): Extracted game resources (maps, vmaps, mmaps, dbc) at `/var/lib/mangos` (read-only mount on mangosd)\n- **VolSync**: Replication configured for backup\n\n## Custom Modules\n\n### Hardcore Mode\n\nPlayers can talk to **\"Masochist\" Pete** (NPC spawned in all major cities) to opt into challenges:\n\n- **Hardcore**: One life, permadeath\n- **Drop Loot**: Drop gear/gold on death\n- **Lose XP**: Lose experience on death\n- **Self Found**: No trading with non-challenge players\n- **PvP Toggle**: Enable/disable PvP during challenges\n\nDatabase migrations are applied via the `cmangos-hardcore-migration` Job.\n\n### Twink Master\n\n**Twink Master** NPCs provide free level 19 BiS gear, consumables, honor items, and endgame no-level-req items:\n\n- **Alliance NPC** (190012): Stormwind Trade District\n- **Horde NPC** (190013): Orgrimmar\n\nVendor categories: BiS Gear, Consumables, Honor Gear, Insane (raid items with no level requirement).\n\nDatabase migrations are applied via the `cmangos-twink-vendor-migration` Job.\n\n## Building the Image\n\nThe Dockerfile uses a multi-stage build:\n\n1. **Builder stage**: Clones CMaNGOS, classic-db, and modules, then compiles with CMake\n2. **Runner stage**: Minimal Ubuntu 24.04 with only runtime dependencies\n\n```bash\ndocker build \\\n  --build-arg THREADS=$(nproc) \\\n  --build-arg MANGOS_SHA1=<commit> \\\n  --build-arg DATABASE_SHA1=<commit> \\\n  -t ghcr.io/xunholy/cmangos-classic:latest \\\n  kubernetes/apps/base/game-servers/cmangos/app/resources/\n```\n\n### Builder Entrypoint Commands\n\nThe builder image provides database management tools:\n\n| Command | Description |\n|---|---|\n| `extract` | Extract game resources (maps, vmaps, mmaps) from WoW client |\n| `init-db` | Initialize all databases from scratch (destructive) |\n| `backup-db` | Backup databases (`-a` all, `-w` world, `-c` characters, `-l` logs, `-r` realmd) |\n| `restore-db` | Restore databases from a backup tar.gz |\n| `update-db` | Apply latest DB updates (`-w` to include world DB refresh) |\n| `manage-db` | Run the InstallFullDB interactive script |\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/achievements-migration-job.yaml",
    "content": "---\n# Achievements module — backports the WotLK achievement system. Imports\n# ~3MB of static achievement/criteria/locale definitions (`achievement_dbc`,\n# `achievement_criteria_dbc`, `achievement_category_dbc`, `achievement_reward`,\n# `achievement_reward_locale`, `achievement_criteria_data`) into classicmangos,\n# plus 2 progress tables (`character_achievement`, `character_achievement_progress`)\n# into classiccharacters.\n#\n# The world-data SQL totals ~3.3MB which exceeds the per-ConfigMap size limit\n# (1MiB), so the SQL is fetched at job time via shallow git clone of\n# xunholy/cmangos-classic rather than inlined. The init container pins to the\n# branch the runtime image was built from — see the cmangos image tag in\n# helmrelease.yaml; bump both in lockstep.\n#\n# Re-running is functionally safe: the upstream SQL uses DROP+CREATE+INSERT\n# on STATIC definition tables only. Player progress lives in `character_achievement*`\n# (separate DB) and is not touched. The achievement IDs are deterministic, so\n# DROP+CREATE+INSERT yields the same definitions and player progress remains\n# valid.\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-achievements-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  # Higher backoffLimit + activeDeadlineSeconds — applying the 3.3MB world SQL\n  # against a cold DB can take a couple of minutes.\n  backoffLimit: 3\n  activeDeadlineSeconds: 1200\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n        - name: clone-source\n          image: alpine/git:latest\n          command:\n            - sh\n            - -c\n            - |\n              set -e\n              git clone --depth 1 --branch main \\\n                https://github.com/xunholy/cmangos-classic.git /shared/src\n              echo \"=== Achievements SQL files ===\"\n              ls -lh /shared/src/src/modules/achievements/sql/install/world/\n              ls -lh /shared/src/src/modules/achievements/sql/install/characters/\n          volumeMounts:\n            - name: shared\n              mountPath: /shared\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              SQL_DIR=\"/shared/src/src/modules/achievements/sql/install\"\n\n              echo \"=== Applying Achievements characters schema ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters < \"$${SQL_DIR}/characters/characters.sql\"\n\n              echo \"=== Applying world_data (achievement_dbc, criteria_dbc, etc) — this is the big one (~1.9MB) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < \"$${SQL_DIR}/world/01_world_data.sql\"\n\n              echo \"=== Applying world_update (rewards / fixups) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < \"$${SQL_DIR}/world/02_world_update.sql\"\n\n              echo \"=== Applying world_locales (~1.2MB) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < \"$${SQL_DIR}/world/03_world_locales.sql\"\n\n              echo \"=== Verifying characters tables ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SHOW TABLES LIKE 'character_achievement%';\"\n\n              echo \"=== Verifying world definition tables ===\"\n              # `rows` is a reserved word in MariaDB 12.2 — use row_count.\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"\n                SELECT 'achievement_dbc'           AS tbl, COUNT(*) AS row_count FROM achievement_dbc UNION ALL\n                SELECT 'achievement_category_dbc',           COUNT(*) FROM achievement_category_dbc UNION ALL\n                SELECT 'achievement_criteria_dbc',           COUNT(*) FROM achievement_criteria_dbc UNION ALL\n                SELECT 'achievement_criteria_data',          COUNT(*) FROM achievement_criteria_data UNION ALL\n                SELECT 'achievement_reward',                 COUNT(*) FROM achievement_reward UNION ALL\n                SELECT 'achievement_reward_locale',          COUNT(*) FROM achievement_reward_locale;\"\n\n              echo \"=== Achievements migration complete ===\"\n          volumeMounts:\n            - name: shared\n              mountPath: /shared\n              readOnly: true\n      volumes:\n        - name: shared\n          emptyDir: {}\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/attunement-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-attunement-migration-sql\n  namespace: game-servers\ndata:\n  characters.sql: |\n    CREATE TABLE IF NOT EXISTS `custom_attunement_player_config` (\n      `guid` int(11) unsigned NOT NULL COMMENT 'Character GUID',\n      `option_key` varchar(64) NOT NULL COMMENT 'Option name (e.g. xp_rate)',\n      `value` float NOT NULL DEFAULT 0 COMMENT 'Option value',\n      `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n      PRIMARY KEY (`guid`, `option_key`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Attunement per-player options';\n  world.sql: |\n    -- ============================================================\n    -- Attunement NPC - \"Attuner of Paths\"\n    -- Single faction-friendly NPC entry: 190014\n    -- Spawns at every Classic starting zone (6 distinct zones, 8 races)\n    -- ============================================================\n\n    SET @AttunementEntry := 190014;\n\n    -- NPC Template: faction 35 = Friendly to all, DisplayId 7949 = ethereal\n    DELETE FROM `creature_template` WHERE `entry` = @AttunementEntry;\n    INSERT INTO `creature_template`\n      (`entry`, `DisplayId1`, `DisplayIdProbability1`, `name`, `subname`, `GossipMenuId`,\n       `minlevel`, `maxlevel`, `faction`, `NpcFlags`, `scale`, `rank`,\n       `DamageSchool`, `MeleeBaseAttackTime`, `RangedBaseAttackTime`, `unitClass`, `unitFlags`,\n       `CreatureType`, `CreatureTypeFlags`, `ScriptName`, `lootid`, `PickpocketLootId`, `SkinningLootId`,\n       `AIName`, `MovementType`, `RacialLeader`, `RegenerateStats`, `MechanicImmuneMask`, `ExtraFlags`)\n    VALUES\n      (@AttunementEntry, 7949, 100, 'Attuner of Paths', 'Adjuster of Fate', 0,\n       60, 60, 35, 1, 1.1, 0,\n       0, 2000, 0, 1, 0,\n       7, 138936390, 'npc_attunement', 0, 0, 0,\n       '', 0, 0, 1, 0, 0);\n\n    -- Spawns: one per Classic starting zone (6 zones, 8 races)\n    DELETE FROM `creature` WHERE `id` = @AttunementEntry;\n    INSERT INTO `creature`\n      (`id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`,\n       `spawntimesecsmin`, `spawntimesecsmax`, `spawndist`, `MovementType`)\n    VALUES\n      -- Coords anchor on the canonical race-start NPC in each zone, offset\n      -- a few units so the Attuner doesn't overlap the existing creature.\n      (@AttunementEntry, 0, 1, -8902.6, -158.6,   82.0, 3.14, 300, 300, 0, 0),  -- Northshire (near Marshal McBride)\n      (@AttunementEntry, 0, 1, -6214.9,  332.2,  383.7, 3.14, 300, 300, 0, 0),  -- Coldridge Valley (near Sten Stoutarm)\n      (@AttunementEntry, 0, 1,  1843.3, 1643.9,   97.8, 3.14, 300, 300, 0, 0),  -- Deathknell (near Shadow Priest Sarvis)\n      (@AttunementEntry, 1, 1, 10328.9,  830.1, 1326.5, 3.14, 300, 300, 0, 0),  -- Shadowglen (near Conservator Ilthalaine)\n      (@AttunementEntry, 1, 1,  -607.4,-4247.3,   39.0, 3.14, 300, 300, 0, 0),  -- Valley of Trials (near Kaltunk)\n      (@AttunementEntry, 1, 1, -2912.7, -253.5,   53.0, 3.14, 300, 300, 0, 0);  -- Camp Narache (near Grull Hawkwind)\n\n    -- NPC Text\n    SET @TEXT_ID := 50930;\n    DELETE FROM `npc_text` WHERE `ID` BETWEEN @TEXT_ID AND @TEXT_ID+1;\n    INSERT INTO `npc_text` (`ID`, `text0_0`) VALUES\n      (@TEXT_ID,\n       'Some walk this world swiftly, others savor every step. I can attune the pace at which experience flows to you, $N. Pick a path - or whisper your own.'),\n      (@TEXT_ID+1,\n       'Whisper the rate you desire, $N. A number such as 1.5 or 7.');\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-attunement-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying Attunement schema to classiccharacters ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters < /sql/characters.sql\n              echo \"=== Characters schema applied successfully ===\"\n\n              echo \"=== Applying Attunement NPC + spawns to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/world.sql\n              echo \"=== World data applied successfully ===\"\n\n              echo \"=== Verifying characters table ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SHOW TABLES LIKE 'custom_attunement%';\"\n\n              echo \"=== Verifying Attunement NPC template ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, name, subname, faction, NpcFlags, ScriptName FROM creature_template WHERE entry = 190014;\"\n\n              echo \"=== Verifying spawns (expect 6 rows) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT id, map, position_x, position_y, position_z FROM creature WHERE id = 190014;\"\n\n              echo \"=== Verifying NPC text ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT ID, LEFT(text0_0, 60) AS text_preview FROM npc_text WHERE ID BETWEEN 50930 AND 50931;\"\n\n              echo \"=== Attunement migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-attunement-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/barber-migration-job.yaml",
    "content": "---\n# Barber module — applies NPC + equipment + gossip text + spawns for the\n# \"Shav Cutiss\" barber (entry 190020). World-only (no characters-DB schema).\n# Idempotent (DELETE-then-INSERT). Pattern matches attunement-migration-job.yaml.\n#\n# Skipped vs upstream world_classic.sql: the gameobject chair migration\n# (id=164767). That migration UPDATEs original Stormwind gameobject IDs which\n# is destructive on re-run — chairs are cosmetic and can be applied manually\n# from src/modules/barber/sql/install/world/world_classic.sql lines 13-22 if\n# desired.\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-barber-migration-sql\n  namespace: game-servers\ndata:\n  world.sql: |\n    SET @Entry := 190020;\n\n    -- Creature template: Shav Cutiss, The Barber (faction 35 = friendly to all)\n    DELETE FROM `creature_template` WHERE `entry` = @Entry;\n    INSERT INTO `creature_template`\n      (Entry, Name, SubName, MinLevel, MaxLevel, DisplayId1, DisplayIdProbability1,\n       Faction, Scale, Family, CreatureType, InhabitType, RegenerateStats, RacialLeader,\n       NpcFlags, UnitFlags, DynamicFlags, ExtraFlags, CreatureTypeFlags, SpeedWalk, SpeedRun,\n       Detection, CallForHelp, Pursuit, Leash, Timeout, UnitClass, `Rank`,\n       HealthMultiplier, PowerMultiplier, DamageMultiplier, DamageVariance, ArmorMultiplier,\n       ExperienceMultiplier, MinLevelHealth, MaxLevelHealth, MinLevelMana, MaxLevelMana,\n       MinMeleeDmg, MaxMeleeDmg, MinRangedDmg, MaxRangedDmg, Armor, MeleeAttackPower,\n       RangedAttackPower, MeleeBaseAttackTime, RangedBaseAttackTime, DamageSchool,\n       MinLootGold, MaxLootGold, LootId, PickpocketLootId, SkinningLootId,\n       KillCredit1, KillCredit2, MechanicImmuneMask, SchoolImmuneMask,\n       ResistanceHoly, ResistanceFire, ResistanceNature, ResistanceFrost, ResistanceShadow, ResistanceArcane,\n       PetSpellDataId, MovementType, TrainerType, TrainerSpell, TrainerClass, TrainerRace,\n       TrainerTemplateId, VendorTemplateId, EquipmentTemplateId, GossipMenuId, AIName)\n    VALUES\n      (@Entry, 'Shav Cutiss', 'The Barber', 60, 60, 7167, 100,\n       35, 1, 0, 7, 3, 3, 0,\n       1, 0, 0, 0, 0, 1, 1.14286,\n       20, 0, 0, 0, 0, 1, 0,\n       1, 1, 1, 1, 1, 1,\n       42, 42, 0, 0,\n       2, 2, 0, 0, 7, 11,\n       0, 2000, 2000, 0,\n       0, 0, 0, 0, 0,\n       0, 0, 0, 0,\n       0, 0, 0, 0, 0, 0,\n       0, 0, 0, 0, 0, 0,\n       0, 0, @Entry, 0, '');\n\n    -- Equipment: dagger (Monster - Bowie Knife)\n    DELETE FROM `creature_equip_template` WHERE `entry` = @Entry;\n    INSERT INTO `creature_equip_template` (entry, equipentry1, equipentry2, equipentry3)\n    VALUES (@Entry, 5278, 0, 0);\n\n    -- Gossip text 50404-50423 (the barber dialog options)\n    DELETE FROM `npc_text` WHERE `ID` BETWEEN 50404 AND 50423;\n    INSERT INTO `npc_text` (`ID`, `text0_0`, `prob0`) VALUES\n      (50404, 'Welcome, friend, to the barbershop! Come for a cut? A coloring? Something else, perhaps?$B$BWe can groom facial hair, perform piercings, ink night elf tattoos, and have a collection of earrings!$B$BHave a seat and we''ll get right to work. You''re only a few coins away from a new, more attractive you...', 1),\n      (50405, 'Cut my hair, barber!', 1),\n      (50406, 'You need 0 copper to pay me.', 1),\n      (50407, 'Please sit down!', 1),\n      (50408, 'Next one!', 1),\n      (50409, 'Previous one!', 1),\n      (50410, 'I''ll have this one.', 1),\n      (50411, 'I want to change my hair style.', 1),\n      (50412, 'I want to change my hair color.', 1),\n      (50413, 'I want to change my facial hair style.', 1),\n      (50414, 'I want to change my horns.', 1),\n      (50415, 'I want to change my horn color.', 1),\n      (50416, 'I want to change my piercings.', 1),\n      (50417, 'I want to change my earrings.', 1),\n      (50418, 'I want to change my markings.', 1),\n      (50419, 'I want to change my face.', 1),\n      (50420, 'I want to change my hair.', 1),\n      (50421, 'I want to change my tusks.', 1),\n      (50422, 'I want to change my tentacles.', 1),\n      (50423, 'Welcome, friend, to the barbershop! Come for a cut? A coloring? Something else, perhaps?$B$BWe can groom facial hair, perform piercings, reshape tusks and horns, and even modify undead features!$B$BHave a seat and we''ll get right to work. You''re only a few coins away from a new, more attractive you...', 1);\n\n    -- Spawns: Stormwind + Orgrimmar\n    DELETE FROM `creature` WHERE `id` = @Entry;\n    INSERT INTO `creature`\n      (`id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`,\n       `spawntimesecsmin`, `spawntimesecsmax`, `spawndist`, `MovementType`)\n    VALUES\n      (@Entry, 0, 1, -8748.08,   651.95, 105.43, 1.82255, 25, 25, 0, 0),  -- Stormwind\n      (@Entry, 1, 1,  1713.69, -4207.01,  51.65, 3.97408, 25, 25, 0, 0);  -- Orgrimmar\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-barber-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying Barber NPC + equip + npc_text + spawns to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/world.sql\n\n              echo \"=== Verifying NPC template ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, name, subname FROM creature_template WHERE entry = 190020;\"\n\n              echo \"=== Verifying spawns (expect 2 rows: Stormwind + Orgrimmar) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT id, map, position_x, position_y FROM creature WHERE id = 190020;\"\n\n              echo \"=== Verifying gossip texts (expect 20 rows: IDs 50404-50423) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT COUNT(*) AS texts_loaded FROM npc_text WHERE ID BETWEEN 50404 AND 50423;\"\n\n              echo \"=== Barber migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-barber-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/dnsendpoint.yaml",
    "content": "---\napiVersion: externaldns.k8s.io/v1alpha1\nkind: DNSEndpoint\nmetadata:\n  name: cmangos-wow\n  annotations:\n    external-dns.alpha.kubernetes.io/external: \"true\"\nspec:\n  endpoints:\n    - dnsName: \"wow.${CLUSTER_DOMAIN}\"\n      recordType: A\n      targets:\n        - \"${EXTERNAL_IP}\"\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/dualspec-migration-job.yaml",
    "content": "---\n# Dualspec module — applies talent/action/character schema + NPC spawn for the\n# Dual Specialization Crystal (entry 190024). Idempotent: CREATE TABLE IF NOT\n# EXISTS for the 4 tables, INSERT IGNORE for the data-seeding inserts from\n# character_action and characters (PK collisions on re-run are harmless).\n#\n# Re-running is safe and preserves existing player dualspec state. The DROP\n# TABLE in the upstream cmangos-classic SQL is intentionally NOT replicated\n# here — that would destroy second-spec talents/action bars on re-run.\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-dualspec-migration-sql\n  namespace: game-servers\ndata:\n  characters.sql: |\n    CREATE TABLE IF NOT EXISTS `custom_dualspec_talent` (\n      `guid`  int(11) unsigned NOT NULL DEFAULT '0',\n      `spell` int(11) unsigned NOT NULL DEFAULT '0',\n      `spec`  tinyint(3) unsigned NOT NULL DEFAULT '0',\n      PRIMARY KEY (`guid`, `spell`, `spec`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\n    CREATE TABLE IF NOT EXISTS `custom_dualspec_talent_name` (\n      `guid` int(11) unsigned NOT NULL DEFAULT '0',\n      `spec` tinyint(3) unsigned NOT NULL DEFAULT '0',\n      `name` varchar(255) NOT NULL DEFAULT '',\n      PRIMARY KEY (`guid`, `spec`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\n    CREATE TABLE IF NOT EXISTS `custom_dualspec_action` (\n      `guid`   int(11) unsigned NOT NULL DEFAULT '0',\n      `button` tinyint(3) unsigned NOT NULL DEFAULT '0',\n      `action` int(11) unsigned NOT NULL DEFAULT '0',\n      `type`   tinyint(3) unsigned NOT NULL DEFAULT '0',\n      `spec`   tinyint(3) unsigned NOT NULL DEFAULT '0',\n      PRIMARY KEY (`guid`, `spec`, `button`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\n    -- Seed spec=0 from existing character_action. INSERT IGNORE so re-runs\n    -- silently skip duplicates (PK guid+spec+button collision).\n    INSERT IGNORE INTO `custom_dualspec_action` (`guid`, `spec`, `button`, `action`, `type`)\n    SELECT `guid`, 0 AS `spec`, `button`, `action`, `type` FROM `character_action`;\n\n    CREATE TABLE IF NOT EXISTS `custom_dualspec_characters` (\n      `guid`        int(11) unsigned NOT NULL DEFAULT '0',\n      `spec_count`  tinyint(3) unsigned NOT NULL DEFAULT '1',\n      `active_spec` tinyint(3) unsigned NOT NULL DEFAULT '0',\n      PRIMARY KEY (`guid`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\n    -- Seed one row per existing character. INSERT IGNORE handles re-runs and\n    -- also picks up any new characters created since the last run.\n    INSERT IGNORE INTO `custom_dualspec_characters` (`guid`)\n    SELECT `guid` FROM `characters`;\n  world.sql: |\n    SET @ENTRY := 190024;\n\n    -- Creature template: Dual Specialization Crystal\n    DELETE FROM `creature_template` WHERE `entry` = @ENTRY;\n    INSERT INTO `creature_template`\n      (Entry, Name, SubName, MinLevel, MaxLevel, DisplayId1, DisplayIdProbability1,\n       Faction, Scale, Family, CreatureType, InhabitType, RegenerateStats, RacialLeader,\n       NpcFlags, UnitFlags, DynamicFlags, ExtraFlags, CreatureTypeFlags, SpeedWalk, SpeedRun,\n       Detection, CallForHelp, Pursuit, Leash, Timeout, UnitClass, `Rank`,\n       HealthMultiplier, PowerMultiplier, DamageMultiplier, DamageVariance, ArmorMultiplier,\n       ExperienceMultiplier, MinLevelHealth, MaxLevelHealth, MinLevelMana, MaxLevelMana,\n       MinMeleeDmg, MaxMeleeDmg, MinRangedDmg, MaxRangedDmg, Armor, MeleeAttackPower,\n       RangedAttackPower, MeleeBaseAttackTime, RangedBaseAttackTime, DamageSchool,\n       MinLootGold, MaxLootGold, LootId, PickpocketLootId, SkinningLootId,\n       KillCredit1, KillCredit2, MechanicImmuneMask, SchoolImmuneMask,\n       ResistanceHoly, ResistanceFire, ResistanceNature, ResistanceFrost, ResistanceShadow, ResistanceArcane,\n       PetSpellDataId, MovementType, TrainerType, TrainerSpell, TrainerClass, TrainerRace,\n       TrainerTemplateId, VendorTemplateId, EquipmentTemplateId, GossipMenuId, AIName)\n    VALUES\n      (@ENTRY, 'Dual Specialization Crystal', '', 1, 1, 11659, 100,\n       35, 1, 0, 7, 3, 3, 0,\n       1, 0, 0, 0, 0, 1, 1.14286,\n       20, 0, 0, 0, 0, 1, 0,\n       1, 1, 1, 1, 1, 1,\n       42, 42, 0, 0,\n       2, 2, 0, 0, 7, 11,\n       0, 2000, 2000, 0,\n       0, 0, 0, 0, 0,\n       0, 0, 0, 0,\n       0, 0, 0, 0, 0, 0,\n       0, 0, 0, 0, 0, 0,\n       0, 0, 0, 0, '');\n\n    -- Spawns: Stormwind + Orgrimmar\n    DELETE FROM `creature` WHERE `id` = @ENTRY;\n    INSERT INTO `creature`\n      (`id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`,\n       `spawntimesecsmin`, `spawntimesecsmax`, `spawndist`, `MovementType`)\n    VALUES\n      (@ENTRY, 0, 1, -8988.56,   849.754, 29.621, 2.27687, 25, 25, 0, 0),\n      (@ENTRY, 1, 1,  1471.63, -4216.46,  58.9942, 4.35778, 25, 25, 0, 0);\n\n    -- Localised name (Spanish)\n    DELETE FROM `locales_creature` WHERE `entry` = @ENTRY;\n    INSERT INTO `locales_creature` (`entry`, `name_loc6`)\n    VALUES (@ENTRY, 'Cristal de Doble Especialización');\n\n    -- mangos_string entries for the dualspec UI (English + Spanish loc6)\n    SET @STRING_ENTRY := 12000;\n    DELETE FROM `mangos_string` WHERE `entry` BETWEEN @STRING_ENTRY AND @STRING_ENTRY+21;\n    INSERT INTO `mangos_string` (`entry`, `content_default`, `content_loc6`) VALUES\n      (@STRING_ENTRY,    'Dual Specialization allows you to quickly switch between two different talent builds and action bars.', 'La doble especialización te permite cambiar rápidamente entre dos construcciones de talento y barras de acción diferentes.'),\n      (@STRING_ENTRY+1,  'The cost is ', 'El precio es '),\n      (@STRING_ENTRY+2,  'Change my specialization.', 'Cambiar mi especialización.'),\n      (@STRING_ENTRY+3,  'You don''t have enough money to unlock dual specialization.', 'No tienes suficiente dinero para desbloquear la doble especialización.'),\n      (@STRING_ENTRY+4,  'Are you sure you would like to activate your second specialization for ', '¿Estás seguro de que te gustaría activar tu segunda especialización por '),\n      (@STRING_ENTRY+5,  ' gold? This will allow you to quickly switch between two different talent builds and action bars.', ' de oro? Esto te permitirá cambiar rápidamente entre dos construcciones de talento y barras de acción diferentes.'),\n      (@STRING_ENTRY+6,  'You are already on that spec.', 'Ya estás en esa especialización.'),\n      (@STRING_ENTRY+7,  '[Activate] ', '[Activar] '),\n      (@STRING_ENTRY+8,  '[Rename] ', '[Renombrar] '),\n      (@STRING_ENTRY+9,  'Unnamed', 'Sin nombre'),\n      (@STRING_ENTRY+10, ' (active)', ' (activa)'),\n      (@STRING_ENTRY+11, 'You are in combat and cannot switch spec at this time.', 'Estás en combate y no puedes cambiar de especialización en este momento.'),\n      (@STRING_ENTRY+12, 'You must exit the instance to re-spec.', 'Debe salir de la estancia para cambiar la especialización.'),\n      (@STRING_ENTRY+13, 'You are mounted and cannot switch spec at this time.', 'Está montado y no puede cambiar la especialización en este momento.'),\n      (@STRING_ENTRY+14, 'You are dead and cannot switch spec at this time.', 'Estás muerto y no puedes cambiar la especialización en este momento.'),\n      (@STRING_ENTRY+15, 'You must unlock the dual talent specialization feature first.', 'Primero debe desbloquear la función de doble especialización.'),\n      (@STRING_ENTRY+16, 'Current level is less than ten - you cannot switch spec at this time.', 'El nivel actual es inferior a diez y no puedes cambiar de especialización en este momento.'),\n      (@STRING_ENTRY+17, '|cFF0041FF[Activate] ', '|cFF0041FF[Activar] '),\n      (@STRING_ENTRY+18, '|cFFCC00CC[Rename] ', '|cFFCC00CC[Renombrar] '),\n      (@STRING_ENTRY+19, 'Are you sure you wish to switch your talent specialization?', '¿Estás seguro de que deseas cambiar su especialización?'),\n      (@STRING_ENTRY+20, 'Purchase Dual Talent Specialization', 'Comprar doble especialización de talentos'),\n      (@STRING_ENTRY+21, 'Can not create dual spec item!', '¡No se puede crear un artículo de doble especialización!');\n\n    -- NPC gossip text\n    SET @TEXT_ID := 50700;\n    DELETE FROM `npc_text` WHERE `ID` BETWEEN @TEXT_ID AND @TEXT_ID+1;\n    INSERT INTO `npc_text` (`ID`, `text0_0`) VALUES\n      (@TEXT_ID,   'Dual Specialization allows you to quickly switch between two different talent builds and action bars.'),\n      (@TEXT_ID+1, 'Dual Specialization allows you to quickly switch between two different talent builds and action bars.');\n\n    DELETE FROM `locales_npc_text` WHERE `entry` BETWEEN @TEXT_ID AND @TEXT_ID+1;\n    INSERT INTO `locales_npc_text` (`entry`, `text0_0_loc6`) VALUES\n      (@TEXT_ID,   'La doble especialización te permite cambiar rápidamente entre dos ramas de talentos y barras de acción diferentes.'),\n      (@TEXT_ID+1, 'La doble especialización te permite cambiar rápidamente entre dos ramas de talentos y barras de acción diferentes.');\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-dualspec-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying Dualspec schema + seeding from character_action/characters ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters < /sql/characters.sql\n\n              echo \"=== Applying Dualspec NPC + strings + spawns to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/world.sql\n\n              echo \"=== Verifying characters tables ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SHOW TABLES LIKE 'custom_dualspec%';\"\n\n              echo \"=== Verifying NPC template (entry 190024 = Dual Specialization Crystal) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, name FROM creature_template WHERE entry = 190024;\"\n\n              echo \"=== Verifying spawns (expect 2 rows: Stormwind + Orgrimmar) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT id, map, position_x, position_y FROM creature WHERE id = 190024;\"\n\n              echo \"=== Verifying mangos_string rows (expect 22 entries: 12000-12021) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT COUNT(*) AS strings_loaded FROM mangos_string WHERE entry BETWEEN 12000 AND 12021;\"\n\n              echo \"=== Dualspec migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-dualspec-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/externalsecret-database.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: cmangos-database-creds\n  namespace: game-servers\nspec:\n  refreshInterval: 1h\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: cmangos-database-creds\n    template:\n      data:\n        # Used by mangosd + realmd to connect to MariaDB.\n        MANGOS_DBUSER: \"{{ .DB_USER }}\"\n        MANGOS_DBPASS: \"{{ .DB_PASSWORD }}\"\n        # Used by the mariadb container at first-init only. Match the\n        # app-user creds so a fresh PVC reproduces the same login.\n        MARIADB_USER: \"{{ .DB_USER }}\"\n        MARIADB_PASSWORD: \"{{ .DB_PASSWORD }}\"\n  dataFrom:\n    - extract:\n        key: cmangos\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/hardcore-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-hardcore-migration-sql\n  namespace: game-servers\ndata:\n  characters.sql: |\n    DROP TABLE IF EXISTS `custom_hardcore_loot_gameobjects`;\n    CREATE TABLE `custom_hardcore_loot_gameobjects` (\n      `id` int(11) unsigned NOT NULL,\n      `player` int(11) unsigned NOT NULL COMMENT 'Player identifier',\n      `loot_id` int(11) unsigned NOT NULL COMMENT 'The loot group this gameobject is part of',\n      `loot_table` int(11) unsigned NOT NULL COMMENT 'custom_hardcore_loot_tables identifier',\n      `money` int(11) unsigned NOT NULL DEFAULT '0',\n      `position_x` float NOT NULL DEFAULT '0',\n      `position_y` float NOT NULL DEFAULT '0',\n      `position_z` float NOT NULL DEFAULT '0',\n      `orientation` float NOT NULL DEFAULT '0',\n      `map` int(11) NOT NULL DEFAULT '0' COMMENT 'Map identifier',\n      `phase_mask` int(11) NOT NULL DEFAULT '0' COMMENT 'Phase mask identifier',\n      PRIMARY KEY (`id`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;\n\n    DROP TABLE IF EXISTS `custom_hardcore_loot_tables`;\n    CREATE TABLE `custom_hardcore_loot_tables` (\n      `id` int(11) unsigned NOT NULL,\n      `item` int(11) unsigned NOT NULL COMMENT 'Item identifier',\n      `amount` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT 'Amount of items',\n      `random_property_id` smallint(5) NOT NULL DEFAULT '0' COMMENT 'The property of the item (e.g. ... of the Hawk, ... of the Monkey)',\n      `durability` int(5) unsigned NOT NULL DEFAULT '0',\n      `enchantments` text,\n      PRIMARY KEY (`id`, `item`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;\n\n    DROP TABLE IF EXISTS `custom_hardcore_grave_gameobjects`;\n    CREATE TABLE `custom_hardcore_grave_gameobjects` (\n      `id` int(11) unsigned NOT NULL,\n      `player` int(11) unsigned NOT NULL COMMENT 'Player identifier',\n      `gameobject_template` int(11) unsigned NOT NULL COMMENT 'gameobject_template entry',\n      `position_x` float NOT NULL DEFAULT '0',\n      `position_y` float NOT NULL DEFAULT '0',\n      `position_z` float NOT NULL DEFAULT '0',\n      `orientation` float NOT NULL DEFAULT '0',\n      `map` int(11) NOT NULL DEFAULT '0' COMMENT 'Map identifier',\n      `phase_mask` int(11) NOT NULL DEFAULT '0' COMMENT 'Phase mask identifier',\n      PRIMARY KEY (`id`, `player`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;\n\n    DROP TABLE IF EXISTS `custom_hardcore_player_config`;\n    CREATE TABLE `custom_hardcore_player_config` (\n      `id` int(11) unsigned NOT NULL,\n      `revive_disabled` boolean DEFAULT FALSE,\n      `drop_loot_on_death` boolean DEFAULT FALSE,\n      `lose_xp_on_death` boolean DEFAULT FALSE,\n      `pvp_disabled` boolean DEFAULT FALSE,\n      `self_found` boolean DEFAULT FALSE,\n      `xp_rate` int(11) unsigned DEFAULT '100',\n      PRIMARY KEY (`id`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;\n\n    DROP TABLE IF EXISTS `custom_hardcore_player_deathlog`;\n    CREATE TABLE `custom_hardcore_player_deathlog` (\n      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,\n      `player` int(11) unsigned NOT NULL,\n      `account` int(11) unsigned NOT NULL,\n      `name` char(100) NOT NULL,\n      `level` int(11) NOT NULL,\n      `zone` int(11) unsigned NOT NULL,\n      `area` int(11) unsigned NOT NULL,\n      `map` int(11) unsigned NOT NULL,\n      `killer` int(11) unsigned NOT NULL,\n      `killer_name` char(100) NOT NULL,\n      `reason` int(11) unsigned NOT NULL,\n      `date` datetime NOT NULL,\n      PRIMARY KEY (`id`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;\n  world.sql: |\n    DELETE FROM gameobject_template WHERE `type`=2 AND `CustomData1`=3643;\n\n    SET @Entry := 190011;\n\n    DELETE FROM `creature_template` WHERE `entry` = @Entry;\n    INSERT INTO `creature_template` (`entry`, `DisplayId1`, `DisplayIdProbability1`, `name`, `subname`, `GossipMenuId`, `minlevel`, `maxlevel`, `faction`, `NpcFlags`, `scale`, `rank`, `DamageSchool`, `MeleeBaseAttackTime`, `RangedBaseAttackTime`, `unitClass`, `unitFlags`, `CreatureType`, `CreatureTypeFlags`, `lootid`, `PickpocketLootId`, `SkinningLootId`, `AIName`, `MovementType`, `RacialLeader`, `RegenerateStats`, `MechanicImmuneMask`, `ExtraFlags`) VALUES\n    (@Entry, 1403, 100, '\"Masochist\" Pete', 'Challenge Advisor', 0, 60, 60, 35, 1, 1, 0, 0, 2000, 0, 1, 0, 7, 138936390, 0, 0, 0, '', 0, 0, 1, 0, 0);\n\n    DELETE FROM `locales_creature` WHERE `entry` = @Entry;\n    INSERT INTO `locales_creature` (`entry`, `name_loc6`, `subname_loc6`) VALUES (@Entry, 'Pedro \"El Masoca\"', 'Asesor de Desafios');\n\n    DELETE FROM `creature` WHERE `id` = @Entry;\n    INSERT INTO `creature` (`id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `spawndist`, `MovementType`) VALUES\n    (@Entry, 0, 1, -8999.00, 851.191, 29.621, 3.88538, 25, 25, 0, 0),\n    (@Entry, 1, 1, 1467.40, -4226.33, 58.9939, 1.19063, 25, 25, 0, 0),\n    (@Entry, 0, 1, -8903.58, -108.401, 81.8486, 4.08677, 25, 25, 0, 0),\n    (@Entry, 0, 1, -6213.26, 330.664, 383.719, 2.89842, 25, 25, 0, 0),\n    (@Entry, 1, 1, 10327.10, 822.521, 1326.43, 2.53681, 25, 25, 0, 0),\n    (@Entry, 1, 1, -638.981, -4227.08, 38.1342, 5.47014, 25, 25, 0, 0),\n    (@Entry, 0, 1, 1859.94, 1560.67, 99.0791, 1.57723, 25, 25, 0, 0),\n    (@Entry, 1, 1, -2882.11, -277.045, 53.9154, 2.37644, 25, 25, 0, 0);\n\n    SET @TEXT_ID := 50900;\n    DELETE FROM `npc_text` WHERE `ID` BETWEEN @TEXT_ID AND @TEXT_ID+16;\n    INSERT INTO `npc_text` (`ID`, `text0_0`) VALUES\n    (@TEXT_ID,    'Ahoy, $N. If you are looking for a challenge you have come to the right place. Tell me, what challenge are you interested in?'),\n    (@TEXT_ID+1,  'Appologies $N. I can''t provide you with any challenges at the moment.'),\n    (@TEXT_ID+2,  'Oh, the hardcore challenge you say? I thought you''d never ask... If you accept this challenge, it means you will only have one life and if you die, that''s it, no more retries. Are you up for it?'),\n    (@TEXT_ID+3,  'Hmm, the drop loot challenge? This challenge will make you drop some of your belongings every time you die, including gear and gold. What do you say?'),\n    (@TEXT_ID+4,  'Ah, the classic lose experience challenge. This challenge will make you lose some experience every time you die, and if you die enough you can even lose levels. Interested?'),\n    (@TEXT_ID+5,  'The self found challenge... I see you are a lone wolf like me. Just to clarify, this means you won''t be able to use any help from any other adventurer, unless they are in the same challenge as you. Ready for it?'),\n    (@TEXT_ID+6,  'Hold your horses cowboy! It seems like your journey has already taken its course. To start this challenge you must speak with me with a fresh start, if you know what I mean...'),\n    (@TEXT_ID+7,  'I know you are excited about this challenge, but you seem like you already accepted it. What do you want, to double accept it?'),\n    (@TEXT_ID+8,  'Hahaha! That''s what I''m talking about! Good luck! You will need it...'),\n    (@TEXT_ID+9,  'Oh, so you don''t want people attacking you during the challenge? That''s cute... But hey, who am I to judge...'),\n    (@TEXT_ID+10, 'All right then... Consider it done. Careful not to break a nail out there.'),\n    (@TEXT_ID+11, 'Are you sure? You won''t be able to retake the challenge if you drop it now.'),\n    (@TEXT_ID+12, 'Oh! That is such a relieve! I was wondering how long were you going to keep joking around...'),\n    (@TEXT_ID+13, 'All done! Enemies will be able to attack you now.'),\n    (@TEXT_ID+14, 'All done! You are no longer doing the challenge.'),\n    (@TEXT_ID+15, 'Which XP rate would you like to have?'),\n    (@TEXT_ID+16, 'All done! You xp rate has been changed.');\n\n    DELETE FROM `locales_npc_text` WHERE `entry` BETWEEN @TEXT_ID AND @TEXT_ID+16;\n    INSERT INTO `locales_npc_text` (`entry`, `text0_0_loc6`) VALUES\n    (@TEXT_ID,    'Hola, $N! Si estas buscando un reto, estas en el lugar indicado. Dime, que reto te interesa?'),\n    (@TEXT_ID+1,  'Mis disculpas $N. No tengo ningun desafio disponible en estos momentos.'),\n    (@TEXT_ID+2,  'El desafio hardcore dices? Crei que nunca me lo preguntarias... Si aceptas este desafio, significa que solo tendras una vida y, si mueres, se acabo, no habra mas reintentos. Te animas?'),\n    (@TEXT_ID+3,  'Mmm, el desafio de perder posesiones? Este desafio te hara soltar algunas de tus pertenencias cada vez que mueras, incluyendo equipo y oro. Que me dices?'),\n    (@TEXT_ID+4,  'Ah, el clasico desafio de perder experiencia. Este desafio te hara perder experiencia cada vez que mueras, y si mueres lo suficiente, incluso puedes perder niveles. Te interesa?'),\n    (@TEXT_ID+5,  'El desafio del lobo solitario... Supongo que eres de los que prefiere ir solo que mal acompanado, eh?. Solo para aclarar, esto significa que no podras usar la ayuda de ningun otro aventurero, a menos que este en el mismo desafio que tu. Estas listo?'),\n    (@TEXT_ID+6,  'Calma, vaquero! Parece que tu viaje ya ha tomado su curso. Para empezar este reto, debes hablar conmigo desde el principio, si sabes a que me refiero...'),\n    (@TEXT_ID+7,  'Se que estas entusiasmado con este reto, pero parece que ya lo has aceptado. Que quieres, aceptarlo dos veces?'),\n    (@TEXT_ID+8,  'Jajaja! Eso es lo que queria escuchar! Mucha suerte! La necesitaras...'),\n    (@TEXT_ID+9,  'Ah, entonces no quieres que otras personas te ataquen durante el desafio? Que monada... Pero bueno, quien soy yo para juzgar?'),\n    (@TEXT_ID+10, 'De acuerdo, ya estas listo. Ve con cuidado por ahi, no vaya a ser que te rompas una una.'),\n    (@TEXT_ID+11, 'Estas seguro? No podras retomar el desafio si lo terminas ahora.'),\n    (@TEXT_ID+12, 'Ah! Que alivio! Ya estaba pensando que de verdad ibas en serio...'),\n    (@TEXT_ID+13, 'Listo! Los enemigos podran combatir contigo ahora.'),\n    (@TEXT_ID+14, 'Listo! Ya no estas realizando el desafio.'),\n    (@TEXT_ID+15, 'Que ratio de XP te gustaria tener?'),\n    (@TEXT_ID+16, 'Listo! He cambiado tu ratio de XP');\n\n    SET @STRING_ENTRY := 12200;\n    DELETE FROM `mangos_string` WHERE `entry` BETWEEN @STRING_ENTRY AND @STRING_ENTRY+14;\n    INSERT INTO `mangos_string` (`entry`, `content_default`, `content_loc6`) VALUES\n    (@STRING_ENTRY,    'I''m interested in the hardcore challenge', 'Estoy interesado en el desafio hardcore'),\n    (@STRING_ENTRY+1,  'I would like to stop doing the hardcore challenge', 'Me gustaria terminar el desafio hardcore'),\n    (@STRING_ENTRY+2,  'I''m interested in the drop loot challenge', 'Estoy interesado en el desafio de perder posesiones'),\n    (@STRING_ENTRY+3,  'I would like to stop doing the drop loot challenge', 'Me gustaria terminar el desafio de perder posesiones'),\n    (@STRING_ENTRY+4,  'I''m interested in the lose experience challenge', 'Estoy interesado en el desafio de perder experiencia'),\n    (@STRING_ENTRY+5,  'I would like to stop doing the lose experience challenge', 'Me gustaria terminar el desafio de perder experiencia'),\n    (@STRING_ENTRY+6,  'I''m interested in the self found challenge', 'Estoy interesado en el desafio del lobo solitario'),\n    (@STRING_ENTRY+7,  'I would like to stop doing the self found challenge', 'Me gustaria terminar el desafio del lobo solitario'),\n    (@STRING_ENTRY+8,  'I would like to change my xp rate', 'Me gustaria cambiar el ratio de XP'),\n    (@STRING_ENTRY+9,  'I accept the challenge!', 'Acepto el desafio!'),\n    (@STRING_ENTRY+10, 'Maybe later...', 'Quizas mas tarde...'),\n    (@STRING_ENTRY+11, 'I would like to disable pvp fights', 'Me gustaria desactivar el combate pvp'),\n    (@STRING_ENTRY+12, 'I would like to enable pvp fights', 'Me gustaria activar el combate pvp'),\n    (@STRING_ENTRY+13, 'Yes, please!', 'Si, por favor!'),\n    (@STRING_ENTRY+14, 'Maybe not...', 'Quizas no...');\n\n    SET @START_SPELL_ID := 33500;\n    SET @END_SPELL_ID := @START_SPELL_ID+1;\n    DELETE FROM `spell_template` WHERE `Id` BETWEEN @START_SPELL_ID AND @END_SPELL_ID;\n    INSERT INTO `spell_template` (`Id`, `School`, `Category`, `CastUI`, `Dispel`, `Mechanic`, `Attributes`, `AttributesEx`, `AttributesEx2`, `AttributesEx3`, `AttributesEx4`, `Stances`, `StancesNot`, `Targets`, `TargetCreatureType`, `RequiresSpellFocus`, `CasterAuraState`, `TargetAuraState`, `CastingTimeIndex`, `RecoveryTime`, `CategoryRecoveryTime`, `InterruptFlags`, `AuraInterruptFlags`, `ChannelInterruptFlags`, `ProcFlags`, `ProcChance`, `ProcCharges`, `MaxLevel`, `BaseLevel`, `SpellLevel`, `DurationIndex`, `PowerType`, `ManaCost`, `ManaCostPerlevel`, `ManaPerSecond`, `ManaPerSecondPerLevel`, `RangeIndex`, `Speed`, `ModalNextSpell`, `StackAmount`, `Totem1`, `Totem2`, `Reagent1`, `Reagent2`, `Reagent3`, `Reagent4`, `Reagent5`, `Reagent6`, `Reagent7`, `Reagent8`, `ReagentCount1`, `ReagentCount2`, `ReagentCount3`, `ReagentCount4`, `ReagentCount5`, `ReagentCount6`, `ReagentCount7`, `ReagentCount8`, `EquippedItemClass`, `EquippedItemSubClassMask`, `EquippedItemInventoryTypeMask`, `Effect1`, `Effect2`, `Effect3`, `EffectDieSides1`, `EffectDieSides2`, `EffectDieSides3`, `EffectBaseDice1`, `EffectBaseDice2`, `EffectBaseDice3`, `EffectDicePerLevel1`, `EffectDicePerLevel2`, `EffectDicePerLevel3`, `EffectRealPointsPerLevel1`, `EffectRealPointsPerLevel2`, `EffectRealPointsPerLevel3`, `EffectBasePoints1`, `EffectBasePoints2`, `EffectBasePoints3`, `EffectMechanic1`, `EffectMechanic2`, `EffectMechanic3`, `EffectImplicitTargetA1`, `EffectImplicitTargetA2`, `EffectImplicitTargetA3`, `EffectImplicitTargetB1`, `EffectImplicitTargetB2`, `EffectImplicitTargetB3`, `EffectRadiusIndex1`, `EffectRadiusIndex2`, `EffectRadiusIndex3`, `EffectApplyAuraName1`, `EffectApplyAuraName2`, `EffectApplyAuraName3`, `EffectAmplitude1`, `EffectAmplitude2`, `EffectAmplitude3`, `EffectMultipleValue1`, `EffectMultipleValue2`, `EffectMultipleValue3`, `EffectChainTarget1`, `EffectChainTarget2`, `EffectChainTarget3`, `EffectItemType1`, `EffectItemType2`, `EffectItemType3`, `EffectMiscValue1`, `EffectMiscValue2`, `EffectMiscValue3`, `EffectTriggerSpell1`, `EffectTriggerSpell2`, `EffectTriggerSpell3`, `EffectPointsPerComboPoint1`, `EffectPointsPerComboPoint2`, `EffectPointsPerComboPoint3`, `SpellVisual`, `SpellIconID`, `ActiveIconID`, `SpellPriority`, `SpellName`, `SpellName2`, `SpellName3`, `SpellName4`, `SpellName5`, `SpellName6`, `SpellName7`, `SpellName8`, `Rank1`, `Rank2`, `Rank3`, `Rank4`, `Rank5`, `Rank6`, `Rank7`, `Rank8`, `ManaCostPercentage`, `StartRecoveryCategory`, `StartRecoveryTime`, `MaxTargetLevel`, `SpellFamilyName`, `SpellFamilyFlags`, `MaxAffectedTargets`, `DmgClass`, `PreventionType`, `StanceBarOrder`, `DmgMultiplier1`, `DmgMultiplier2`, `DmgMultiplier3`, `MinFactionId`, `MinReputation`, `RequiredAuraVision`, `EffectBonusCoefficient1`, `EffectBonusCoefficient2`, `EffectBonusCoefficient3`, `EffectBonusCoefficientFromAP1`, `EffectBonusCoefficientFromAP2`, `EffectBonusCoefficientFromAP3`, `IsServerSide`, `AttributesServerside`) VALUES\n    (@START_SPELL_ID, 0, 0, 0, 0, 0, 2147483648, 0, 0, 1048576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 1, 1, 21, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 6, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 61, 0, 0, 'Hardcore Challenge', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1, 1, 0, 0, 0, 1, 0.2, 0, 0, 0, 0, 0, 0),\n    (@START_SPELL_ID+1, 0, 0, 0, 0, 0, 2147483648, 0, 0, 1048576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 1, 1, 21, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 6, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 1573, 0, 0, 'Self Found Challenge', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1, 1, 0, 0, 0, 1, 0.2, 0, 0, 0, 0, 0, 0);\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-hardcore-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying hardcore module schema to classiccharacters ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters < /sql/characters.sql\n              echo \"=== Characters schema applied successfully ===\"\n\n              echo \"=== Applying hardcore module data to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/world.sql\n              echo \"=== World data applied successfully ===\"\n\n              echo \"=== Verifying characters tables ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SHOW TABLES LIKE 'custom_hardcore%';\"\n\n              echo \"=== Verifying Masochist Pete NPC ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, name, subname FROM creature_template WHERE entry = 190011;\"\n\n              echo \"=== Verifying creature spawns ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT COUNT(*) AS spawn_count FROM creature WHERE id = 190011;\"\n\n              echo \"=== Hardcore module migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-hardcore-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/hearthstone-cd-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-hearthstone-cd-migration-sql\n  namespace: game-servers\ndata:\n  hearthstone-15m.sql: |\n    -- Hearthstone (item 6948) cooldown: 1h → 15m.\n    --\n    -- The cooldown lives on the spell (8690), not the item — cmangos reads\n    -- spell data from the SQL spell_template table at world load, so an\n    -- UPDATE here is the canonical override (no DBC file edit needed).\n    --\n    -- RecoveryTime is in milliseconds. 900000ms = 15 * 60s * 1000ms.\n    -- Idempotent: re-running this just rewrites the same value.\n    --\n    -- Canonical copy lives in the fork at:\n    --   etc/emberstone/sql/world/hearthstone-15m.sql\n    -- Keep this inline copy in sync with that file.\n    --\n    -- Note: spell_template is loaded at mangosd startup. The cooldown change\n    -- takes effect on the next mangosd restart, not immediately.\n\n    -- Spell 8690 has BOTH RecoveryTime and CategoryRecoveryTime; engine\n    -- uses MAX(both). Updating just RecoveryTime leaves the Category\n    -- (89 = Hearthstone) at 60min, so the effective CD stays 60min.\n    -- Update both to 900000 (15min).\n    UPDATE `spell_template`\n       SET `RecoveryTime`         = 900000,\n           `CategoryRecoveryTime` = 900000\n     WHERE `Id` = 8690;\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-hearthstone-cd-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying Hearthstone 15m cooldown override to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/hearthstone-15m.sql\n              echo \"=== SQL applied ===\"\n\n              echo \"=== Verifying spell 8690 (Hearthstone) RecoveryTime ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT id, SpellName, RecoveryTime FROM spell_template WHERE id = 8690;\"\n\n              echo \"=== Done. Restart mangosd to pick up the new cooldown ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-hearthstone-cd-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: cmangos\n  namespace: game-servers\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      database:\n        containers:\n          app:\n            image:\n              repository: mariadb\n              tag: \"12.2\"\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              # MARIADB_ROOT_PASSWORD is first-init-only (DB volume is\n              # persistent; ignored on subsequent starts). Rotation is\n              # tracked separately from the app user.\n              MARIADB_ROOT_PASSWORD: password\n              MARIADB_DATABASE: classicrealmd\n            envFrom:\n              # MARIADB_USER / MARIADB_PASSWORD come from 1Password via\n              # ExternalSecret (cmangos-database-creds). First-init only.\n              - secretRef:\n                  name: cmangos-database-creds\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['healthcheck.sh', '--connect', '--innodb_initialized']\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['healthcheck.sh', '--connect', '--innodb_initialized']\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  exec:\n                    command: ['healthcheck.sh', '--connect', '--innodb_initialized']\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 2Gi\n      realmd:\n        initContainers:\n          wait-db:\n            image:\n              repository: busybox\n              tag: latest\n            command: ['sh', '-c', 'until nc -z cmangos-database 3306; do sleep 2; done']\n        containers:\n          app:\n            image:\n              repository: ghcr.io/xunholy/cmangos-classic\n              tag: 2473619f4ff3431fe68bacec5b05fa52fa0e0fba\n            args: [\"realmd\"]\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              MANGOS_DBHOST: cmangos-database\n              MANGOS_DBPORT: \"3306\"\n            envFrom:\n              # MANGOS_DBUSER + MANGOS_DBPASS from 1Password via ESO.\n              - secretRef:\n                  name: cmangos-database-creds\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 3724\n                  periodSeconds: 5\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 10m\n                memory: 64Mi\n              limits:\n                memory: 256Mi\n      mangosd:\n        pod:\n          terminationGracePeriodSeconds: 300\n        initContainers:\n          wait-db:\n            image:\n              repository: busybox\n              tag: latest\n            command: ['sh', '-c', 'until nc -z cmangos-database 3306; do sleep 2; done']\n        containers:\n          app:\n            image:\n              repository: ghcr.io/xunholy/cmangos-classic\n              tag: 2473619f4ff3431fe68bacec5b05fa52fa0e0fba\n            args: [\"mangosd\"]\n            tty: true\n            stdin: true\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              MANGOS_DBHOST: cmangos-database\n              MANGOS_DBPORT: \"3306\"\n            envFrom:\n              # MANGOS_DBUSER + MANGOS_DBPASS from 1Password via ESO.\n              - secretRef:\n                  name: cmangos-database-creds\n            # Graceful shutdown via the existing stdin FIFO. Aligned with\n            # terminationGracePeriodSeconds=300: send 'server restart 240'\n            # (4-min in-game countdown), then sleep 260s for save + exit.\n            # SIGTERM follows at ~280s, SIGKILL at 300s if anything lingers.\n            lifecycle:\n              preStop:\n                exec:\n                  command:\n                    - /bin/sh\n                    - -c\n                    - |\n                      echo \"server restart 240\" > /tmp/mangosd-stdin\n                      sleep 260\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8085\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 180\n            resources:\n              requests:\n                cpu: \"2\"\n                memory: 4Gi\n              limits:\n                memory: 12Gi\n          # Tail the GM audit log to stdout so commands issued by\n          # GM-tier accounts surface in kubectl logs (and the eventual\n          # Loki collector). The mangosd container writes gm.log; this\n          # sidecar shares the cmangos-mangosd-logs PVC read-only.\n          gm-log-tail:\n            image:\n              repository: busybox\n              tag: latest\n            command:\n              - /bin/sh\n              - -c\n              - |\n                while [ ! -f /opt/mangos/logs/gm.log ]; do sleep 5; done\n                exec tail -F /opt/mangos/logs/gm.log\n            resources:\n              requests:\n                cpu: 5m\n                memory: 8Mi\n              limits:\n                memory: 32Mi\n            securityContext:\n              runAsUser: 1001\n              runAsGroup: 1001\n              runAsNonRoot: true\n              readOnlyRootFilesystem: true\n              allowPrivilegeEscalation: false\n              capabilities:\n                drop: [\"ALL\"]\n          # Prune /opt/mangos/cores so a runaway crash loop can't fill\n          # the 40Gi PVC again (May 2026 incident: cores went from a\n          # 4-9 GB dump to zero-byte writes once the disk was full,\n          # blinding post-mortem analysis). Keeps the 2 newest non-zero\n          # cores by mtime and deletes the rest every 10 min.\n          cores-pruner:\n            image:\n              repository: busybox\n              tag: latest\n            command:\n              - /bin/sh\n              - -c\n              - |\n                while true; do\n                  if cd /opt/mangos/cores 2>/dev/null; then\n                    find . -maxdepth 1 -name 'core.*' -size 0 -delete 2>/dev/null\n                    # shellcheck disable=SC2012\n                    ls -1t core.* 2>/dev/null | tail -n +3 | xargs -r rm -f --\n                  fi\n                  sleep 600\n                done\n            resources:\n              requests:\n                cpu: 5m\n                memory: 8Mi\n              limits:\n                memory: 32Mi\n            securityContext:\n              # mangosd writes cores as the mangos user (UID 1001). Without\n              # CAP_DAC_OVERRIDE (we drop ALL caps) root can't delete files\n              # owned by 1001 at mode 0600, so the pruner becomes a no-op\n              # and the cores PVC wedges at 100%. Match the worldserver UID.\n              runAsUser: 1001\n              runAsGroup: 1001\n              runAsNonRoot: true\n              readOnlyRootFilesystem: true\n              allowPrivilegeEscalation: false\n              capabilities:\n                drop: [\"ALL\"]\n    service:\n      database:\n        controller: database\n        ports:\n          mysql:\n            port: 3306\n      auth:\n        controller: realmd\n        ports:\n          auth:\n            port: 3724\n      world:\n        controller: mangosd\n        ports:\n          world:\n            port: 8085\n      soap:\n        controller: mangosd\n        ports:\n          soap:\n            port: 7878\n    configMaps:\n      mangosd-config:\n        data:\n          mangosd.conf: |\n            GameType = 1\n            RealmZone = 8\n            WorldServerPort = 8085\n            BindIP = \"0.0.0.0\"\n            PlayerLimit = 750\n            # Serialize MapUpdater workers to eliminate concurrent navmesh + bot-AI races.\n            # Confirmed root cause of the BG segfaults at 250-500 bots: cores show concurrent\n            # MapUpdateWorker threads crashing in dtNavMesh::getTileAt and ai::MovementAction::UseTransport.\n            # detour is not thread-safe; UseTransport has unguarded sGOStorage::LookupEntry deref.\n            MapUpdate.Threads = 1\n            Motd = \"Welcome to Emberstone\"\n            LogLevel = 3\n            LogFile = \"/opt/mangos/logs/Server.log\"\n            LogFileLevel = 3\n            LogTimestamp = 1\n            # GM command audit log. Absolute path because run_mangosd cd's\n            # into /opt/mangos/cores before exec. Tailed by the gm-log-tail\n            # sidecar so lines also reach kubectl logs / future Loki.\n            GmLogFile = \"/opt/mangos/logs/gm.log\"\n            GmLogTimestamp = 1\n            GmLogPerAccount = 0\n            LogGMTrade = 1\n            LogFilter_GMChat = 0\n            SOAP.Enabled = 1\n            SOAP.IP = 0.0.0.0\n            SOAP.Port = 7878\n            Rate.XP.Kill = 1\n            Rate.XP.Quest = 1\n            Rate.XP.Explore = 1\n            Rate.Drop.Item.Poor = 3\n            Rate.Drop.Item.Normal = 3\n            Rate.Drop.Item.Uncommon = 3\n            Rate.Drop.Item.Rare = 2\n            Rate.Drop.Item.Epic = 1\n            Rate.Drop.Money = 3\n            Rate.Reputation.Gain = 3\n            AllowTwoSide.Interaction.Group = 1\n            AllowTwoSide.Interaction.Guild = 1\n            AllowTwoSide.Interaction.Chat = 1\n            AllowTwoSide.Interaction.Channel = 1\n            MailDeliveryDelay = 0\n            StartPlayerMoney = 100000\n            SkillGain.Crafting = 3\n            SkillGain.Gathering = 3\n            SkillGain.Defense = 3\n            SkillGain.Weapon = 3\n            Rate.Drop.Item.Quest = 3\n            Death.Ghost.RunSpeed.World = 1.5\n            PlayerSaveInterval = 60000\n            Rate.Health = 3\n            Rate.Mana = 3\n      realmd-config:\n        data:\n          realmd.conf: |\n            RealmServerPort = 3724\n            BindIP = \"0.0.0.0\"\n            # Brute-force protection on the SRP6 auth port (internet\n            # exposed via TCPRoute → envoy-external gateway).\n            #   MaxCount=5  failures before action\n            #   BanTime=600 ten-minute ban\n            #   BanType=1   ban by IP (0 = ban the account, riskier)\n            #   Logging=1   log every failure so Crowdsec / Falco can\n            #               pick up patterns and broaden the response\n            WrongPass.MaxCount = 5\n            WrongPass.BanTime = 600\n            WrongPass.BanType = 1\n            WrongPass.Logging = 1\n      aiplayerbot-config:\n        data:\n          aiplayerbot.conf: |\n            AiPlayerbot.Enabled = 1\n            AiPlayerbot.RandomBotAutoCreate = 1\n            AiPlayerbot.RandomBotAutologin = 1\n            # Boot-time bot stampede was segfaulting mangosd at \"Loading\n            # instance data for world_map_kalimdor\": 250+ bots spawning\n            # into maps 0/1 raced detour navmesh + sGOStorage::LookupEntry\n            # before map state settled. MapUpdate.Threads=1 fixes the BG\n            # runtime case but not the startup case. Bots ramp up over\n            # time after boot via the random-bot tick, so we still reach\n            # MinRandomBots without the boot stampede.\n            AiPlayerbot.RandomBotLoginAtStartup = 0\n            AiPlayerbot.RandomBotAccountPrefix = rndbot\n            AiPlayerbot.RandomBotAccountCount = 2000\n            AiPlayerbot.MinRandomBots = 1000\n            AiPlayerbot.MaxRandomBots = 2000\n            AiPlayerbot.RandomBotMinLevel = 1\n            AiPlayerbot.RandomBotMaxLevel = 60\n            AiPlayerbot.RandomBotMaps = 0,1\n            AiPlayerbot.AutoDoQuests = 1\n            AiPlayerbot.AutoPickReward = yes\n            AiPlayerbot.AutoEquipUpgradeLoot = 1\n            AiPlayerbot.AutoLearnTrainerSpells = 1\n            AiPlayerbot.AutoLearnQuestSpells = 1\n            AiPlayerbot.RandomGearUpgradeEnabled = 1\n            AiPlayerbot.RandomBotTeleportNearPlayer = 1\n            AiPlayerbot.SyncQuestWithPlayer = 1\n            AiPlayerbot.RandomBotGuildCount = 0\n            AiPlayerbot.RandomBotJoinBG = 1\n            # Temporary: stop bots auto-queuing into BGs. Crashes traced to\n            # HandleMoveWorldportAckOpcode racing a fresh BG removal — bots\n            # cycling in/out of queues are what supplies the stale Worldport\n            # ACKs. Re-enable once the WorldportAck patch (0002) lands in\n            # the image. Bots still queue when invited (RandomBotJoinBG=1).\n            AiPlayerbot.RandomBotAutoJoinBG = 0\n            AiPlayerbot.RandomBotGroupNearby = 1\n            AiPlayerbot.SyncLevelWithPlayers = 1\n            AiPlayerbot.SyncLevelMaxAbove = 2\n            AiPlayerbot.AutoPickTalents = full\n            AiPlayerbot.AutoTrainSpells = free\n            # Competitive BG/WSG twink settings\n            AiPlayerbot.minEnchantingBotLevel = 10\n            AiPlayerbot.BotAcceptDuelMinimumLevel = 10\n      twinkmaster-config:\n        data:\n          twinkmaster.conf: |\n            Twinkmaster.Enable = 1\n            Twinkmaster.TargetLevel = 19\n      attunement-config:\n        data:\n          # Hardcore was amalgamated into the Attuner of Paths gossip\n          # in xunholy/cmangos-classic@feb8ea8b7 — the merged module\n          # reads both Attunement.* and Hardcore.* keys from this single\n          # attunement.conf. (The old hardcore.conf path is no longer\n          # consulted by the binary.)\n          attunement.conf: |\n            Attunement.Enable = 1\n            Attunement.DefaultRate = 1.0\n            Attunement.MinRate = 0.1\n            Attunement.MaxRate = 100\n            Attunement.Aura.Tier1.SpellId = 0\n            Attunement.Aura.Tier2.SpellId = 0\n            Attunement.Aura.Tier3.SpellId = 0\n            Attunement.Aura.Tier4.SpellId = 0\n            Attunement.Aura.Tier5.SpellId = 0\n            Hardcore.Enable = 1\n            Hardcore.PlayerConfig = 1\n            Hardcore.BroadcastDeathGuild = 1\n            Hardcore.BroadcastDeathWorld = 1\n            Hardcore.SpawnGrave = 1\n            Hardcore.GraveGameObjectID = 61\n            Hardcore.GraveMessage = \"Shit happens. <PlayerName> | Well, this sucks. <PlayerName> | It is really dark down here. <PlayerName> | Finally some peace and quiet. <PlayerName> | Shhh! I am sleeping. <PlayerName>\"\n            Hardcore.RemoveGravesOnCharacterDeleted = 1\n            Hardcore.DropGear = 0\n            Hardcore.DropItems = 0\n            Hardcore.DropMoney = 0\n            Hardcore.BotDropGear = 0\n            Hardcore.BotDropItems = 0\n            Hardcore.BotDropMoney = 0\n            Hardcore.RemoveLootOnCharacterDeleted = 1\n            Hardcore.LootGameObjectID = 2850\n            Hardcore.ReviveDisabled = 1\n            Hardcore.ReviveOnGraveyard = 0\n            Hardcore.LevelDown = 0\n            Hardcore.MaxPlayerLoot = 99\n            Hardcore.DropOnDungeons = 1\n            Hardcore.DropOnRaids = 1\n            Hardcore.LevelDownOnDungeons = 1\n            Hardcore.LevelDownOnRaids = 1\n            Hardcore.LevelDownMinLevel = 1\n            Hardcore.DropMinLevel = 1\n            Hardcore.DisablePVP = 0\n            Hardcore.SelfFound = 0\n      anticheat-config:\n        data:\n          # Canonical source: etc/emberstone/anticheat.conf in\n          # xunholy/cmangos-classic. Keep in sync.\n          # Action mask vocabulary (sum of bits): 1=log, 2=prompt,\n          # 4=kick, 8=ban_acct, 16=ban_ip, 32=silence. Every mask here\n          # is ≤ 7 — kick-only, never auto-ban (human decision only).\n          anticheat.conf: |\n            [AnticheatConf]\n            ConfVersion=2017102301\n            Enable = 1\n            FingerprintHistory = 30\n            FingerprintLevel = 6\n            KickDelay.Min = 30\n            KickDelay.Max = 90\n            BanDelay.Min = 30\n            BanDelay.Max = 90\n            IPBanDelay.Min = 30\n            IPBanDelay.Max = 90\n            BanWave.Day = 1\n            BanWave.Hour = 10\n            BanWave.Minute = 0\n            Movement.UseExtrapolation = 1\n            Movement.SpeedHack.Enable  = 1\n            Movement.WallClimb.TickCount   = 0\n            Movement.WallClimb.TickAction  = 0\n            Movement.WallClimb.TotalCount  = 0\n            Movement.WallClimb.TotalAction = 0\n            # High-confidence cheats — kick on first detect\n            Movement.WaterWalk.TickCount   = 1\n            Movement.WaterWalk.TickAction  = 7\n            Movement.WaterWalk.TotalCount  = 0\n            Movement.WaterWalk.TotalAction = 0\n            Movement.SlowFall.TickCount   = 1\n            Movement.SlowFall.TickAction  = 7\n            Movement.SlowFall.TotalCount  = 0\n            Movement.SlowFall.TotalAction = 0\n            Movement.FlyHack.TickCount    = 1\n            Movement.FlyHack.TickAction   = 7\n            Movement.FlyHack.TotalCount   = 0\n            Movement.FlyHack.TotalAction  = 0\n            Movement.Forbidden.TickCount  = 1\n            Movement.Forbidden.TickAction = 7\n            Movement.Forbidden.TotalCount = 0\n            Movement.Forbidden.TotalAction= 0\n            Movement.NullClientTime.TickCount  = 1\n            Movement.NullClientTime.TickAction = 7\n            Movement.NullClientTime.TotalCount = 0\n            Movement.NullClientTime.TotalAction = 0\n            Movement.RootMove.TickCount  = 1\n            Movement.RootMove.TickAction = 7\n            Movement.RootMove.TotalCount = 0\n            Movement.RootMove.TotalAction= 0\n            Movement.TimeBack.TickCount  = 1\n            Movement.TimeBack.TickAction = 7\n            Movement.TimeBack.TotalCount = 0\n            Movement.TimeBack.TotalAction= 0\n            Movement.FakeTransport.TickCount   = 1\n            Movement.FakeTransport.TickAction  = 7\n            Movement.FakeTransport.TotalCount  = 0\n            Movement.FakeTransport.TotalAction = 0\n            Movement.TeleToTransport.TickCount  = 1\n            Movement.TeleToTransport.TickAction = 7\n            Movement.TeleToTransport.TotalCount = 0\n            Movement.TeleToTransport.TotalAction= 0\n            Movement.FixedZ.TickCount  = 1\n            Movement.FixedZ.TickAction = 7\n            Movement.FixedZ.TotalCount = 0\n            Movement.FixedZ.TotalAction= 0\n            # Twitchy under lag — log+prompt, kick after 10 cumulative\n            Movement.MultiJump.TickCount    = 1\n            Movement.MultiJump.TickAction   = 3\n            Movement.MultiJump.TotalCount   = 10\n            Movement.MultiJump.TotalAction  = 7\n            Movement.FastJump.TickCount     = 1\n            Movement.FastJump.TickAction    = 3\n            Movement.FastJump.TotalCount    = 10\n            Movement.FastJump.TotalAction   = 7\n            Movement.JumpSpeedChange.TickCount  = 1\n            Movement.JumpSpeedChange.TickAction = 3\n            Movement.JumpSpeedChange.TotalCount = 10\n            Movement.JumpSpeedChange.TotalAction= 7\n            Movement.HeartbeatSkip.TickCount  = 1\n            Movement.HeartbeatSkip.TickAction = 3\n            Movement.HeartbeatSkip.TotalCount = 10\n            Movement.HeartbeatSkip.TotalAction= 7\n            Movement.ClockDesync.TickCount  = 1\n            Movement.ClockDesync.TickAction = 3\n            Movement.ClockDesync.TotalCount = 10\n            Movement.ClockDesync.TotalAction= 7\n            # Mid-confidence — kick after 3-5 cumulative\n            Movement.OverspeedZ.TickCount   = 1\n            Movement.OverspeedZ.TickAction  = 3\n            Movement.OverspeedZ.TotalCount  = 5\n            Movement.OverspeedZ.TotalAction = 7\n            Movement.BadOrderAck.TickCount  = 1\n            Movement.BadOrderAck.TickAction = 3\n            Movement.BadOrderAck.TotalCount = 5\n            Movement.BadOrderAck.TotalAction= 7\n            # Teleport — instant kick on first detect. Position revert is\n            # built into the anticheat: src/game/Anticheat/module/Movement/\n            # movement.cpp:1034 calls Player::SavePositionInDB with the\n            # PREVIOUS (legitimate) position and returns false to reject\n            # the movement opcode. So a hacker teleporting to GM island\n            # gets kicked AND the DB stores their pre-cheat location, so\n            # relog doesn't keep them there.\n            # GM island has an extra CHEAT_TYPE_FORBIDDEN detector at\n            # movement.cpp:1031.\n            # No false-positive concern: engine-initiated teleports (mage\n            # portal, hearthstone, instance entry, gryphon arrivals) are\n            # excluded from this check — only client-injected movements\n            # the server didn't request trip it.\n            Movement.Teleport.TickCount     = 1\n            Movement.Teleport.TickAction    = 7\n            Movement.Teleport.TotalCount    = 0\n            Movement.Teleport.TotalAction   = 0\n            Movement.TeleportFar.TickCount  = 1\n            Movement.TeleportFar.TickAction = 7\n            Movement.TeleportFar.TotalCount = 0\n            Movement.TeleportFar.TotalAction= 0\n            # Exploration — info only, no kick\n            Movement.Explore.TickCount     = 3\n            Movement.Explore.TickAction    = 3\n            Movement.Explore.TotalCount    = 0\n            Movement.Explore.TotalAction   = 0\n            Movement.ExploreHigh.TickCount  = 1\n            Movement.ExploreHigh.TickAction = 3\n            Movement.ExploreHigh.TotalCount  = 0\n            Movement.ExploreHigh.TotalAction = 0\n            Movement.BadFallReset.Enable    = 1\n            Movement.BadFallReset.Threshold = 1\n            Movement.BadFallReset.Penalty   = 7\n            # Antispam — silence (reversible)\n            Antispam.Enable   = 1\n            Antispam.Silence  = 1\n            Antispam.MaxLevel = 25\n            # Warden re-enable attempt. Previous crash was 'Failed to locate\n            # Warden modules' — root cause hypothesis: relative path\n            # \"warden_modules\" doesn't resolve at the moment WardenModuleMgr\n            # lazy-initializes on first player auth (boost::fs::exists from\n            # a CWD that isn't /opt/mangos/bin). Switching to absolute path\n            # rules out CWD-resolution issues; data files at this path are\n            # confirmed present + readable + size-valid + non-zero header.\n            Warden.Enable                       = 1\n            Warden.ModuleDir                    = \"/opt/mangos/bin/warden_modules\"\n            Warden.Timeout                      = 30\n            Warden.ScanFrequency                = 15\n            Warden.ScanCount                    = 10\n            Warden.MinimumLevel                 = 1\n            Warden.MinimumAdvancedLevel         = 1\n            Warden.SuspiciousEndSceneHookAction = 7\n            Warden.TickCount                    = 1\n            Warden.TickAction                   = 7\n            Warden.TotalCount                   = 0\n            Warden.TotalAction                  = 0\n      vip-config:\n        data:\n          # merge_confs in the runner entrypoint splits each line on '=' and\n          # uses LHS as the key. Section headers ([VipConf]) and # comments\n          # don't parse as key=value, so they end up appended as garbage\n          # '[VipConf] = [VipConf]' lines in /opt/mangos/etc/vip.conf.\n          # Keep this to plain key=value only, matching attunement.conf.\n          # MasterSpellId 22888 = Rallying Cry of the Dragonslayer.\n          # Vanilla 1.12.1 client has it in spell.dbc (renders in\n          # spellbook with that name + icon 1548). Zero references from\n          # creatures, items, or AI scripts in this server's DB, so\n          # reusing the ID does not collide with any in-game content.\n          # The vanilla effects (10% crit / 140 AP / 5% spell crit, 2h)\n          # ride along with whatever bundled spells get added below.\n          # Previous ID 91200 (\"Wayfarer's Boon\") is Cataclysm-range\n          # and invisible to vanilla clients without a custom patch-X.MPQ.\n          vip.conf: |\n            Vip.Enable = 1\n            Vip.MasterSpellId = 18282\n            # Explicit list (rather than \"\" which the mangos config parser\n            # returns as a literal 2-char string, not an empty string —\n            # the module's empty-string fallback to built-in defaults\n            # never triggered).\n            # Bundle (15 spells):\n            #   22888 Rallying Cry of the Dragonslayer  16609 Warchief's Blessing\n            #   24425 Spirit of Zandalar                 15366 Songflower Serenade\n            #   22817 Fengus' Ferocity   22818 Mol'dar's Moxie   22820 Slip'kik's Savvy   (DM Tribute trio)\n            #   23735 Sayge's Strength   23736 Sayge's Agility   23737 Sayge's Stamina    (Sayge Dark Fortunes)\n            #   23768 Sayge's Damage     26393 Elune's Blessing  (Lunar Festival)\n            #   17626 Flask of the Titans  17627 Distilled Wisdom  17628 Supreme Power\n            Vip.BundledSpellIds = 22888,24425,15366,16609,22817,22818,22820,23735,23736,23737,23768,26393,17626,17627,17628\n      autoscale-config:\n        data:\n          autoscale.conf: |\n            Autoscale.Enable = 1\n            Autoscale.RescanIntervalSeconds = 10\n            Autoscale.HpExponent = 0.85\n            Autoscale.MinScale = 0.20\n            Autoscale.MaxScale = 1.0\n            # Baselines reflect each raid's designed group size. MC/BWL/\n            # AQ40/Onyxia were built for 40, ZG/AQ20 for 20. The\n            # MinScale=0.20 floor catches small-group attempts (e.g. 5p\n            # MC at the floor = 20% HP) — the \"smallest party we'll\n            # bother supporting\" tier. Adding bodies scales mobs back up\n            # toward 100% smoothly.\n            Autoscale.Baseline.Dungeon = 5\n            Autoscale.Baseline.RaidDefault = 40\n            Autoscale.MapBaselines = \"309:20,509:20\"\n            Autoscale.MapBlacklist = \"\"\n            Autoscale.Announce = 1\n      transmog-config:\n        data:\n          transmog.conf: |\n            Transmog.Enable = 1\n            # Per-transmog gold cost (copper). 0 = free.\n            Transmog.CostFee = 0\n            # Multiplier on item-quality-based cost (1.0 = no extra cost).\n            Transmog.CostMultiplier = 1.0\n            # Token-gated transmog (0 = disabled, no token required).\n            Transmog.TokenRequired = 0\n            Transmog.TokenEntry = 0\n            Transmog.TokenAmount = 1\n      barber-config:\n        data:\n          barber.conf: |\n            Barber.Enable = 1\n      dualspec-config:\n        data:\n          dualspec.conf: |\n            Dualspec.Enable = 1\n            # Cost to unlock second spec, in copper (100000 = 10g).\n            Dualspec.Cost = 100000\n      trainingdummies-config:\n        data:\n          trainingdummies.conf: |\n            Trainingdummies.Enable = 1\n      achievements-config:\n        data:\n          achievements.conf: |\n            Achievements.Enable = 1\n            # Chat broadcast when an achievement is earned (1 = on).\n            Achievements.SendMessage = 1\n            # Send special packets for the client-side \"Achiever\" addon (1 = on).\n            Achievements.SendAddon = 1\n            # Visual sparkle effect on the player when earning achievement (1 = on).\n            Achievements.SendVisual = 1\n            # Spell ID for the visual effect.\n            Achievements.EffectId = 146\n            # Award achievements to random bots (0 = off — bots clutter realm-first leaderboards).\n            Achievements.RandomBots = 0\n            Achievements.RandomBotsRealmFirst = 0\n            # Sync earned achievements across all characters of an account (0 = per-character).\n            Achievements.AccountAchievements = 0\n      ahbot-config:\n        data:\n          ahbot.conf: |\n            AuctionHouseBot.Seller.Enabled = 1\n            AuctionHouseBot.Buyer.Enabled = 1\n            AuctionHouseBot.Chance.Sell = 80\n            AuctionHouseBot.Chance.Buy = 40\n            AuctionHouseBot.Alliance.Items.Amount.Ratio = 100\n            AuctionHouseBot.Horde.Items.Amount.Ratio = 100\n            AuctionHouseBot.Neutral.Items.Amount.Ratio = 80\n            AuctionHouseBot.Buy.Value = 90\n            AuctionHouseBot.Bid.Min = 60\n            AuctionHouseBot.Bid.Max = 95\n            AuctionHouseBot.Time.Min = 2\n            AuctionHouseBot.Time.Max = 48\n            AuctionHouseBot.Value.Variance = 15\n            AuctionHouseBot.Items.Profession = 90, 100, 0, 60\n            AuctionHouseBot.Loot.Creature.Normal = 40, 50, 8, 15\n            AuctionHouseBot.Loot.Creature.Elite = 35, 40, 2, 4\n            AuctionHouseBot.Loot.Creature.Rare = 5, 15, 1, 2\n            AuctionHouseBot.Loot.Disenchant = 15, 20, 1, 3\n            AuctionHouseBot.Loot.Fishing = 5, 10, 30, 50\n            AuctionHouseBot.Loot.Gameobject = 20, 25, 7, 15\n            AuctionHouseBot.Loot.Skinning = 5, 10, 50, 80\n    persistence:\n      database:\n        existingClaim: cmangos-database\n        advancedMounts:\n          database:\n            app:\n              - path: /var/lib/mysql\n      data:\n        existingClaim: cmangos-data\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /var/lib/mangos\n                readOnly: true\n      cores:\n        existingClaim: cmangos-cores\n        advancedMounts:\n          mangosd:\n            app:\n              # Mount as a sibling of /opt/mangos/etc so that mangosd's\n              # default config lookups (../etc/X.conf for aiplayerbot,\n              # ahbot, twinkmaster) keep resolving when we chdir here\n              # for core-dump capture.\n              - path: /opt/mangos/cores\n            cores-pruner:\n              - path: /opt/mangos/cores\n      mangosd-config:\n        type: configMap\n        name: cmangos-mangosd-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/mangosd.conf\n                subPath: mangosd.conf\n      realmd-config:\n        type: configMap\n        name: cmangos-realmd-config\n        advancedMounts:\n          realmd:\n            app:\n              - path: /opt/mangos/conf/realmd.conf\n                subPath: realmd.conf\n      aiplayerbot-config:\n        type: configMap\n        name: cmangos-aiplayerbot-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/aiplayerbot.conf\n                subPath: aiplayerbot.conf\n      twinkmaster-config:\n        type: configMap\n        name: cmangos-twinkmaster-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/twinkmaster.conf\n                subPath: twinkmaster.conf\n      attunement-config:\n        type: configMap\n        name: cmangos-attunement-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/attunement.conf\n                subPath: attunement.conf\n      anticheat-config:\n        type: configMap\n        name: cmangos-anticheat-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/anticheat.conf\n                subPath: anticheat.conf\n      vip-config:\n        type: configMap\n        name: cmangos-vip-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/vip.conf\n                subPath: vip.conf\n      autoscale-config:\n        type: configMap\n        name: cmangos-autoscale-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/autoscale.conf\n                subPath: autoscale.conf\n      transmog-config:\n        type: configMap\n        name: cmangos-transmog-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/transmog.conf\n                subPath: transmog.conf\n      barber-config:\n        type: configMap\n        name: cmangos-barber-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/barber.conf\n                subPath: barber.conf\n      dualspec-config:\n        type: configMap\n        name: cmangos-dualspec-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/dualspec.conf\n                subPath: dualspec.conf\n      trainingdummies-config:\n        type: configMap\n        name: cmangos-trainingdummies-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/trainingdummies.conf\n                subPath: trainingdummies.conf\n      achievements-config:\n        type: configMap\n        name: cmangos-achievements-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/achievements.conf\n                subPath: achievements.conf\n      ahbot-config:\n        type: configMap\n        name: cmangos-ahbot-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/ahbot.conf\n                subPath: ahbot.conf\n      mangosd-logs:\n        existingClaim: cmangos-mangosd-logs\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/logs\n            gm-log-tail:\n              - path: /opt/mangos/logs\n                readOnly: true\n      realmd-logs:\n        type: emptyDir\n        advancedMounts:\n          realmd:\n            app:\n              - path: /opt/mangos/logs\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - externalsecret-database.yaml\n  - pvc-database.yaml\n  - pvc-data.yaml\n  - pvc-cores.yaml\n  - pvc-logs.yaml\n  - tcproutes.yaml\n  - dnsendpoint.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n  - prometheusrule.yaml\n  - mangos-string-517-migration-job.yaml\n  - lookup-gm-security-migration-job.yaml\n  # Vendored module migrations (cmangos-classic@main src/modules/*).\n  # Comment-out individual lines for a staged rollout — all 5 modules also\n  # gated by their .conf Enable= key in helmrelease.yaml.\n  - transmog-migration-job.yaml\n  - barber-migration-job.yaml\n  - dualspec-migration-job.yaml\n  - trainingdummies-migration-job.yaml\n  - achievements-migration-job.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/lookup-gm-security-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-lookup-gm-security-migration-sql\n  namespace: game-servers\ndata:\n  # Stock CMaNGOS ships the read-only .lookup subcommands (item, creature,\n  # quest, spell, object, itemset, faction, skill, taxinode) at security\n  # level 3 (Administrator). That blocks GMs (level 2) from basic lookups\n  # like \".lookup item Hearthstone\" — needed to ID NPCs/items/spells when\n  # answering player tickets. The commands are read-only (return IDs, no\n  # world mutation), so granting them to GMs is safe.\n  #\n  # `.reload command` in the mangosd console picks the change up without\n  # a worldserver restart.\n  lookup-gm-security.sql: |\n    UPDATE `command`\n       SET `security` = 2\n     WHERE `name` IN (\n       'lookup creature',\n       'lookup faction',\n       'lookup item',\n       'lookup itemset',\n       'lookup object',\n       'lookup quest',\n       'lookup skill',\n       'lookup spell',\n       'lookup taxinode'\n     );\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-lookup-gm-security-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Lowering .lookup subcommands to GM (security=2) in classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/lookup-gm-security.sql\n\n              # PTR shares the schema; apply there too so a fresh PTR rebuild\n              # lands on the same policy.\n              if mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" -e \"USE ptrmangos\" 2>/dev/null; then\n                echo \"=== Lowering .lookup subcommands in ptrmangos ===\"\n                mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" ptrmangos < /sql/lookup-gm-security.sql\n              fi\n\n              echo \"=== Verifying ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos \\\n                -e \"SELECT name, security FROM command WHERE name LIKE 'lookup%' ORDER BY name;\"\n\n              echo \"=== Done. Run '.reload command' in the mangosd console (no restart needed) ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-lookup-gm-security-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/mangos-string-517-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-mangos-string-517-migration-sql\n  namespace: game-servers\ndata:\n  # mangos_string row 517 (LANG_GO_MIXED_LIST_CHAT) drifted away from\n  # what the C++ call site at Level2.cpp expects. The drifted format\n  # had an extra \"%d\" in the Hgameobject:%d:%d link and put SpawnGroup\n  # outside the |h|r link tags, giving 11 placeholders against 10\n  # args. vsnprintf then walked past the supplied varargs and ran\n  # strlen on uninitialised stack bits — repeatable SIGSEGV on any\n  # .gobject near / delete / target from a GM near gameobjects.\n  #\n  # Three cores on 2026-05-18 (12:56, 12:58, 13:02) all had identical\n  # stacks: __strlen_avx2 → vfprintf → PSendSysMessage. Root-cause\n  # write-up: see patches/0003-go-mixed-list-hardcoded-format.patch.\n  #\n  # Canonical format matches upstream sql/base/mangos.sql:3865. Patch\n  # 0003 also hardcodes the format at both call sites so this row no\n  # longer matters to the worldserver — keep this migration anyway so\n  # any future DB rebuild starts from a sane row.\n  mangos-string-517.sql: |\n    UPDATE `mangos_string`\n       SET `content_default` = '%d%s, Entry %d - |cffffffff|Hgameobject:%d|h[%s X:%f Y:%f Z:%f MapId:%d]SpawnGroup:%u|h|r'\n     WHERE `entry` = 517;\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-mangos-string-517-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Repairing classicmangos.mangos_string row 517 ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/mangos-string-517.sql\n\n              # PTR shares the schema; if it exists, apply there too so a\n              # fresh PTR rebuild also lands on a sane row.\n              if mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" -e \"USE ptrmangos\" 2>/dev/null; then\n                echo \"=== Repairing ptrmangos.mangos_string row 517 ===\"\n                mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" ptrmangos < /sql/mangos-string-517.sql\n              fi\n\n              echo \"=== Verifying ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos \\\n                -e \"SELECT entry, content_default FROM mangos_string WHERE entry = 517 \\G\"\n\n              echo \"=== Done. Worldserver must be restarted to reload mangos_string ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-mangos-string-517-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/prometheusrule.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/prometheusrule_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  name: game-servers-rules\n  namespace: game-servers\nspec:\n  groups:\n    # ─── Availability ───────────────────────────────────────────────────────\n    - name: game-servers.availability\n      interval: 1m\n      rules:\n        - alert: GameServerDown\n          expr: |\n            kube_deployment_status_replicas_available{\n              namespace=\"game-servers\",\n              deployment=~\"cmangos-mangosd|cmangos-realmd|cmangos-database|azerothcore-worldserver|azerothcore-authserver|azerothcore-database|emberstone-portal\"\n            } == 0\n          for: 2m\n          labels:\n            severity: critical\n            team: game-servers\n          annotations:\n            summary: \"{{ $labels.deployment }} is down (no ready replicas)\"\n            description: |\n              Deployment `{{ $labels.deployment }}` in namespace `{{ $labels.namespace }}` has had zero\n              ready replicas for at least 2 minutes. Players cannot connect.\n\n        - alert: GameServerDegraded\n          expr: |\n            (\n              kube_deployment_status_replicas{\n                namespace=\"game-servers\",\n                deployment=~\"cmangos-.*|azerothcore-.*|emberstone-portal\"\n              } -\n              kube_deployment_status_replicas_available{\n                namespace=\"game-servers\",\n                deployment=~\"cmangos-.*|azerothcore-.*|emberstone-portal\"\n              }\n            ) > 0\n          for: 10m\n          labels:\n            severity: warning\n            team: game-servers\n          annotations:\n            summary: \"{{ $labels.deployment }} degraded ({{ $value }} replicas missing)\"\n            description: |\n              Deployment `{{ $labels.deployment }}` has had fewer ready replicas than desired for\n              10+ minutes. Service may still be reachable but is in a degraded state.\n\n    # ─── Crash-loop detection ───────────────────────────────────────────────\n    # Multiple thresholds to catch both fast loops (every 30s) and slow\n    # loops (every few minutes). The slow-loop case is what slipped through\n    # on 2026-05-02 when mangosd was segfaulting every ~6 min on a single\n    # corrupt player record — too sparse for [15m]>5 to fire, too transient\n    # for KubePodCrashLooping to settle.\n    - name: game-servers.crashloop\n      interval: 1m\n      rules:\n        - alert: GameServerCrashLooping\n          expr: |\n            increase(kube_pod_container_status_restarts_total{\n              namespace=\"game-servers\"\n            }[15m]) >= 3\n          for: 5m\n          labels:\n            severity: critical\n            team: game-servers\n          annotations:\n            summary: \"{{ $labels.pod }} restarted {{ $value }} times in the last 15 min\"\n            description: |\n              Pod `{{ $labels.pod }}` in namespace `{{ $labels.namespace }}` is crash-looping\n              ({{ $value }} restarts in 15 minutes). Likely application bug or unhealthy\n              dependency; check `kubectl logs --previous` and `kubectl describe pod`.\n\n        - alert: GameServerRecentRestarts\n          # Slow but persistent restart pattern — catches anything restarting\n          # >= 3 times per hour, which a 6-min crash cycle hits easily.\n          expr: |\n            increase(kube_pod_container_status_restarts_total{\n              namespace=\"game-servers\"\n            }[1h]) >= 3\n          for: 10m\n          labels:\n            severity: warning\n            team: game-servers\n          annotations:\n            summary: \"{{ $labels.pod }} has restarted {{ $value }} times in the last hour\"\n            description: |\n              Pod `{{ $labels.pod }}` is restarting at a rate of >= 3/hour. Could be a\n              slow crash loop (e.g., one specific event triggers a segfault that takes\n              minutes to recur). Examine `kubectl logs --previous` for the exit cause.\n\n        - alert: GameServerSegfault\n          # Container exited via signal (exit code 137=SIGKILL, 139=SIGSEGV).\n          # 139 specifically means the process crashed at the binary level.\n          expr: |\n            kube_pod_container_status_last_terminated_exitcode{\n              namespace=\"game-servers\"\n            } == 139\n          for: 1m\n          labels:\n            severity: critical\n            team: game-servers\n          annotations:\n            summary: \"{{ $labels.pod }} segfaulted (exit code 139)\"\n            description: |\n              Pod `{{ $labels.pod }}` in `{{ $labels.namespace }}` exited via SIGSEGV.\n              Likely indicates a binary-level bug or corrupt input data. Check\n              `kubectl logs --previous` for the stack trace and any preceding errors.\n\n    # ─── Storage health (the class of bug that took us down today) ──────────\n    - name: game-servers.storage\n      interval: 1m\n      rules:\n        - alert: GameServerVolumeReadOnly\n          expr: |\n            node_filesystem_readonly{\n              mountpoint=~\"/var/lib/kubelet/pods/.*\",\n              fstype!~\"tmpfs|overlay|nsfs\"\n            } == 1\n          for: 1m\n          labels:\n            severity: critical\n            team: game-servers\n          annotations:\n            summary: \"A pod volume on {{ $labels.instance }} is mounted read-only\"\n            description: |\n              Filesystem `{{ $labels.mountpoint }}` on `{{ $labels.instance }}` is read-only.\n              Usually triggered by `errors=remount-ro` after underlying I/O errors (Ceph RBD\n              session loss, disk failure). Pods using this volume will be unable to write —\n              **force-recreate the pod** to remap the volume after underlying storage recovers.\n\n        - alert: GameServerPVCNearFull\n          expr: |\n            (\n              kubelet_volume_stats_available_bytes{namespace=\"game-servers\"}\n              /\n              kubelet_volume_stats_capacity_bytes{namespace=\"game-servers\"}\n            ) < 0.10\n          for: 15m\n          labels:\n            severity: warning\n            team: game-servers\n          annotations:\n            summary: \"PVC {{ $labels.persistentvolumeclaim }} is {{ $value | humanizePercentage }} free\"\n            description: |\n              Game-server PVC is below 10% free space. Expand the PVC or clean up data\n              before writes start failing.\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/pvc-cores.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: cmangos-cores\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 40Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/pvc-data.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: cmangos-data\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/pvc-database.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: cmangos-database\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/pvc-logs.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: cmangos-mangosd-logs\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/realm-address-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-realm-address-migration-sql\n  namespace: game-servers\ndata:\n  realmd.sql: |\n    UPDATE realmlist\n    SET address = '${EXTERNAL_IP}'\n    WHERE id = 1;\n    SELECT id, name, address, port FROM realmlist WHERE id = 1;\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-realm-address-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Updating realm address to external gateway IP ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicrealmd < /sql/realmd.sql\n              echo \"=== Realm address migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-realm-address-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/realm-pvp-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-realm-pvp-migration-sql\n  namespace: game-servers\ndata:\n  realm-pvp.sql: |\n    -- Flip the realm to PvP type.\n    -- realmlist.icon: 0=Normal, 1=PvP, 4=Normal, 6=RP, 8=RPPvP. Must match\n    -- mangosd.conf GameType for the lobby badge + in-game enforcement to\n    -- agree. Single-realm setup — no WHERE filter. Idempotent.\n    --\n    -- Canonical copy: etc/emberstone/sql/realmd/realm-pvp.sql in\n    -- xunholy/cmangos-classic.\n    UPDATE `realmlist`\n       SET `icon` = 1;\n  pvp-state-reset.sql: |\n    -- Clean stale per-character PvP / BG state at the realm-type flip.\n    -- character_battleground_data tracks active BG slot + queue. After a\n    -- realm-type change, lingering rows can reference BGs that no longer\n    -- exist — same crash class as the 0002-WorldportAck patch. Honor /\n    -- kill totals are NOT touched; those are durable progression stats.\n    -- playerFlags PvP bits are derived per-tick by mangosd, no migration\n    -- needed there.\n    --\n    -- Canonical copy: etc/emberstone/sql/characters/pvp-state-reset.sql in\n    -- xunholy/cmangos-classic.\n    TRUNCATE TABLE `character_battleground_data`;\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-realm-pvp-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Setting realmlist.icon=1 on classicrealmd ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicrealmd < /sql/realm-pvp.sql\n\n              echo \"=== Wiping stale BG state on classiccharacters ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters < /sql/pvp-state-reset.sql\n\n              echo \"=== Verifying realm icon ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicrealmd -e \"SELECT id, name, icon FROM realmlist;\"\n\n              echo \"=== Verifying BG state cleared ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SELECT COUNT(*) AS remaining_bg_rows FROM character_battleground_data;\"\n\n              echo \"=== Done. Restart mangosd+realmd to pick up the new realm type ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-realm-pvp-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: cmangos-database\nspec:\n  sourcePVC: cmangos-database\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: cmangos-database-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/tcproutes.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: cmangos-auth\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: cmangos-auth\n  rules:\n    - backendRefs:\n        - name: cmangos-auth\n          port: 3724\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: cmangos-world\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: cmangos-world\n  rules:\n    - backendRefs:\n        - name: cmangos-world\n          port: 8085\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/trainingdummies-migration-job.yaml",
    "content": "---\n# Trainingdummies module — spawns 3 dummy NPCs (Grandmaster/Advanced/Beginner)\n# at multiple training locations across Eastern Kingdoms + Kalimdor. World-only\n# (no characters-DB schema). Idempotent (DELETE-then-INSERT).\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-trainingdummies-migration-sql\n  namespace: game-servers\ndata:\n  world.sql: |\n    -- 3 dummy NPC templates. Faction 7 = Stormwind (player-attackable for melee\n    -- training), CreatureTypeFlags 64 = \"interactable target dummy\" hint.\n    DELETE FROM `creature_template` WHERE `entry` IN (190021, 190022, 190023);\n    INSERT INTO `creature_template`\n      (Entry, Name, SubName, MinLevel, MaxLevel, DisplayId1, DisplayIdProbability1,\n       Faction, Scale, Family, CreatureType, InhabitType, RegenerateStats, RacialLeader,\n       NpcFlags, UnitFlags, DynamicFlags, ExtraFlags, CreatureTypeFlags, SpeedWalk, SpeedRun,\n       Detection, CallForHelp, Pursuit, Leash, Timeout, UnitClass, `Rank`,\n       HealthMultiplier, PowerMultiplier, DamageMultiplier, DamageVariance, ArmorMultiplier,\n       ExperienceMultiplier, MinLevelHealth, MaxLevelHealth, MinLevelMana, MaxLevelMana,\n       MinMeleeDmg, MaxMeleeDmg, MinRangedDmg, MaxRangedDmg, Armor, MeleeAttackPower,\n       RangedAttackPower, MeleeBaseAttackTime, RangedBaseAttackTime, DamageSchool,\n       MinLootGold, MaxLootGold, LootId, PickpocketLootId, SkinningLootId,\n       KillCredit1, KillCredit2, MechanicImmuneMask, SchoolImmuneMask,\n       ResistanceHoly, ResistanceFire, ResistanceNature, ResistanceFrost, ResistanceShadow, ResistanceArcane,\n       PetSpellDataId, MovementType, TrainerType, TrainerSpell, TrainerClass, TrainerRace,\n       TrainerTemplateId, VendorTemplateId, EquipmentTemplateId, GossipMenuId, AIName, ScriptName)\n    VALUES\n      (190021, 'Grandmaster''s Training Dummy', '', 63, 63, 16074, 100, 7, 2.2, 0, 9, 3, 0, 0, 0, 32768, 0, 64, 4, 1, 1.14286, 20, 0, 0, 0, 0, 1, 3, 1000, 1, 1, 1, 1, 1, 7888000, 7888000, 0, 0, 0, 0, 0, 0, 4700, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8585235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', ''),\n      (190022, 'Advanced Training Dummy',         '', 61, 61, 3019,  100, 7, 1.8, 0, 9, 3, 3, 0, 0, 0,     0, 64, 0, 1, 1.14286, 20, 0, 0, 0, 0, 1, 1, 200,  1, 1, 1, 1, 1, 1397200, 1397200, 0, 0, 2, 2, 0, 0, 3700, 0, 0, 2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 8585235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', ''),\n      (190023, 'Beginner Training Dummy',         '', 60, 60, 3019,  100, 7, 1.2, 0, 9, 3, 3, 0, 0, 0,     0, 64, 0, 1, 1.14286, 20, 0, 0, 0, 0, 1, 0, 200,  1, 1, 1, 1, 1, 1397200, 1397200, 0, 0, 2, 2, 0, 0, 3000, 0, 0, 2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0, 8585235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '');\n\n    -- Spanish localisations\n    DELETE FROM `locales_creature` WHERE `entry` IN (190021, 190022, 190023);\n    INSERT INTO `locales_creature` (`entry`, `name_loc6`, `subname_loc6`) VALUES\n      (190021, 'Muñeco de entrenamiento mayor',      ''),\n      (190022, 'Muñeco de entrenamiento avanzado',   ''),\n      (190023, 'Muñeco de entrenamiento basico',     '');\n\n    -- Spawns: 6 locations × 3 dummies = 18 rows. Locations are the major\n    -- city / class-trainer areas in Classic. Some coords (10000+, 2258+)\n    -- are TBC-only and inert on Classic but kept for upstream fidelity.\n    DELETE FROM `creature` WHERE `id` IN (190021, 190022, 190023);\n    INSERT INTO `creature`\n      (`id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`,\n       `spawntimesecsmin`, `spawntimesecsmax`, `spawndist`, `MovementType`)\n    VALUES\n      -- Grandmaster (190021)\n      (190021, 1, 1, -1416.73,   -76.4812, 158.526, 1.04029, 25, 25, 0, 0),\n      (190021, 0, 1,  1768.18,   352.747,  -62.2883, 4.4141, 25, 25, 0, 0),\n      (190021, 1, 1,  2151.77, -4632.69,    50.4428, 3.59001, 25, 25, 0, 0),\n      (190021, 1, 1, 10000.5,   2258.5,   1329.8,    3.99055, 25, 25, 0, 0),\n      (190021, 0, 1, -4910.96, -1151.19,   501.449,  3.09082, 25, 25, 0, 0),\n      (190021, 0, 1, -8795.57,   363.195,  101.021,  5.41645, 25, 25, 0, 0),\n      -- Advanced (190022)\n      (190022, 1, 1, -1422.05,   -72.171,  157.476,  0.693121, 25, 25, 0, 0),\n      (190022, 0, 1,  1780.49,   333.857,  -62.2898, 2.37992,  25, 25, 0, 0),\n      (190022, 1, 1,  2152.63, -4639.71,    50.3799, 3.22873,  25, 25, 0, 0),\n      (190022, 1, 1, 10006.2,   2252.62,  1329.75,   3.99449,  25, 25, 0, 0),\n      (190022, 0, 1, -4936.94, -1138.88,   501.46,   6.12402,  25, 25, 0, 0),\n      (190022, 0, 1, -8789.85,   367.182,  101.021,  5.33006,  25, 25, 0, 0),\n      -- Beginner (190023)\n      (190023, 1, 1, -1410.51,   -78.656,  158.935,  1.37014,  25, 25, 0, 0),\n      (190023, 0, 1,  1783.91,   341.82,   -62.3358, 2.8865,   25, 25, 0, 0),\n      (190023, 1, 1,  2148.06, -4627.23,    50.9305, 3.88454,  25, 25, 0, 0),\n      (190023, 1, 1,  9993.03,  2260.47,  1330.81,   4.48136,  25, 25, 0, 0),\n      (190023, 0, 1, -4938.02, -1148.3,    501.497,  6.14209,  25, 25, 0, 0),\n      (190023, 0, 1, -8800.62,   358.618,  101.021,  5.44787,  25, 25, 0, 0);\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-trainingdummies-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying Trainingdummies NPCs + locales + spawns to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/world.sql\n\n              echo \"=== Verifying NPC templates (expect 3 rows: 190021/22/23) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, name FROM creature_template WHERE entry IN (190021, 190022, 190023);\"\n\n              echo \"=== Verifying spawns (expect 18 rows: 6 locations × 3 dummies) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT id, COUNT(*) AS spawn_count FROM creature WHERE id IN (190021, 190022, 190023) GROUP BY id;\"\n\n              echo \"=== Trainingdummies migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-trainingdummies-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/transmog-migration-job.yaml",
    "content": "---\n# Transmog module — applies schema for the appearance system and spawns the\n# Magister Stellaria NPC (entry 190010). Idempotent (CREATE TABLE IF NOT\n# EXISTS, DELETE-then-INSERT) so Flux can recreate the Job after ttl expires\n# without damage. Pattern matches attunement-migration-job.yaml.\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-transmog-migration-sql\n  namespace: game-servers\ndata:\n  characters.sql: |\n    CREATE TABLE IF NOT EXISTS `custom_transmog_active` (\n      `item_guid` int(11) unsigned NOT NULL,\n      `transmog_entry` int(11) unsigned NOT NULL,\n      `player` int(11) unsigned NOT NULL,\n      PRIMARY KEY (`item_guid`),\n      KEY `player` (`player`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\n    CREATE TABLE IF NOT EXISTS `custom_transmog_discovered` (\n      `player` int(11) unsigned NOT NULL,\n      `item_entry` int(11) unsigned NOT NULL,\n      PRIMARY KEY (`player`, `item_entry`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n  world.sql: |\n    -- Transmog NPC: Magister Stellaria (entry 190010)\n    -- Spawn coords avoid overlap with attunement's Attuner of Paths (190014)\n    -- and dualspec's NPC (190024). See cmangos-classic 39b23109f.\n\n    SET @Entry := 190010;\n\n    DELETE FROM `creature_template` WHERE `entry` = @Entry;\n    INSERT INTO `creature_template`\n      (`entry`, `DisplayId1`, `DisplayIdProbability1`, `name`, `subname`, `GossipMenuId`,\n       `minlevel`, `maxlevel`, `faction`, `NpcFlags`, `scale`, `rank`,\n       `DamageSchool`, `MeleeBaseAttackTime`, `RangedBaseAttackTime`, `unitClass`, `unitFlags`,\n       `CreatureType`, `CreatureTypeFlags`, `lootid`, `PickpocketLootId`, `SkinningLootId`,\n       `AIName`, `MovementType`, `RacialLeader`, `RegenerateStats`, `MechanicImmuneMask`, `ExtraFlags`)\n    VALUES\n      (@Entry, 2240, 100, 'Magister Stellaria', 'Transmogrifier', 0,\n       60, 60, 35, 1, 1, 0,\n       0, 2000, 0, 1, 0,\n       7, 138936390, 0, 0, 0,\n       '', 0, 0, 1, 0, 0);\n\n    DELETE FROM `creature` WHERE `id` = @Entry;\n    INSERT INTO `creature`\n      (`id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`,\n       `spawntimesecsmin`, `spawntimesecsmax`, `spawndist`, `MovementType`)\n    VALUES\n      (@Entry, 0, 1, -8930.96,   770.06, 100.21, 4.70, 25, 25, 0, 0),  -- Stormwind Trade District tailor area\n      (@Entry, 1, 1,  1623.00, -4419.00,  22.00, 4.00, 25, 25, 0, 0);  -- Orgrimmar Drag's tailor district\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-transmog-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying Transmog schema to classiccharacters ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters < /sql/characters.sql\n\n              echo \"=== Applying Transmog NPC + spawns to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/world.sql\n\n              echo \"=== Verifying characters tables ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SHOW TABLES LIKE 'custom_transmog%';\"\n\n              echo \"=== Verifying NPC template ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, name, subname FROM creature_template WHERE entry = 190010;\"\n\n              echo \"=== Verifying spawns (expect 2 rows: Stormwind + Orgrimmar) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT id, map, position_x, position_y FROM creature WHERE id = 190010;\"\n\n              echo \"=== Transmog migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-transmog-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/twink-vendor-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-twink-vendor-migration-sql\n  namespace: game-servers\ndata:\n  characters.sql: |\n    CREATE TABLE IF NOT EXISTS `custom_twinkmaster_player_config` (\n      `guid` int(11) unsigned NOT NULL COMMENT 'Character GUID',\n      `xp_locked` boolean DEFAULT FALSE COMMENT 'Whether XP gain is blocked',\n      `level_set` boolean DEFAULT FALSE COMMENT 'Whether level was set by Twink Master',\n      `created_at` datetime DEFAULT CURRENT_TIMESTAMP,\n      PRIMARY KEY (`guid`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Twink Master player configuration';\n  world.sql: |\n    -- ============================================================\n    -- Twink Master NPC - Level 19 Multi-Vendor\n    -- Alliance: 190012 | Horde: 190013\n    -- Categories: 1=BiS Gear, 2=Consumables, 3=Honor Gear, 4=Insane\n    -- ============================================================\n\n    SET @AllianceEntry := 190012;\n    SET @HordeEntry := 190013;\n\n    -- NPC Templates: Alliance (Stormwind faction) + Horde (Orgrimmar faction)\n    DELETE FROM `creature_template` WHERE `entry` IN (@AllianceEntry, @HordeEntry);\n    INSERT INTO `creature_template` (`entry`, `DisplayId1`, `DisplayIdProbability1`, `name`, `subname`, `GossipMenuId`, `minlevel`, `maxlevel`, `faction`, `NpcFlags`, `scale`, `rank`, `DamageSchool`, `MeleeBaseAttackTime`, `RangedBaseAttackTime`, `unitClass`, `unitFlags`, `CreatureType`, `CreatureTypeFlags`, `ScriptName`, `lootid`, `PickpocketLootId`, `SkinningLootId`, `AIName`, `MovementType`, `RacialLeader`, `RegenerateStats`, `MechanicImmuneMask`, `ExtraFlags`) VALUES\n    (@AllianceEntry, 3455, 100, 'Twink Master', 'Level 19 Specialist', 0, 19, 19, 12, 5, 1, 0, 0, 2000, 0, 1, 0, 7, 138936390, 'npc_twinkmaster', 0, 0, 0, '', 0, 0, 1, 0, 0),\n    (@HordeEntry,    1374, 100, 'Twink Master', 'Level 19 Specialist', 0, 19, 19, 85, 5, 1, 0, 0, 2000, 0, 1, 0, 7, 138936390, 'npc_twinkmaster', 0, 0, 0, '', 0, 0, 1, 0, 0);\n\n    -- Spawns: Stormwind Trade District (Alliance) + Orgrimmar WSG area (Horde)\n    DELETE FROM `creature` WHERE `id` IN (@AllianceEntry, @HordeEntry);\n    INSERT INTO `creature` (`id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecsmin`, `spawntimesecsmax`, `spawndist`, `MovementType`) VALUES\n    (@AllianceEntry, 0, 1, -8830.0, 665.0, 97.9, 0.65, 25, 25, 0, 0),\n    (@HordeEntry,    1, 1, 1986.0, -4785.0, 55.82, 4.26, 25, 25, 0, 0);\n\n    -- NPC Text\n    SET @TEXT_ID := 50920;\n    DELETE FROM `npc_text` WHERE `ID` BETWEEN @TEXT_ID AND @TEXT_ID+2;\n    INSERT INTO `npc_text` (`ID`, `text0_0`) VALUES\n    (@TEXT_ID,   'Welcome, $N! Looking to gear up for the battleground? I have everything a level 19 champion needs. Browse my wares - everything is on the house!'),\n    (@TEXT_ID+1, 'Ready to lock in at level 19? I can set your level and lock your experience so you stay in peak form for Warsong Gulch.'),\n    (@TEXT_ID+2, 'Only the finest equipment for aspiring twinks. May your battles be glorious, $N!');\n\n    -- ============================================================\n    -- Vendor Category Table (read by C++ module)\n    -- Discrete values: 1=BiS Gear, 2=Consumables, 3=Honor Gear, 4=Insane\n    -- ============================================================\n    DROP TABLE IF EXISTS `custom_twinkmaster_vendor_categories`;\n    CREATE TABLE `custom_twinkmaster_vendor_categories` (\n      `item` int(11) unsigned NOT NULL,\n      `categories` tinyint(3) unsigned NOT NULL DEFAULT 1,\n      PRIMARY KEY (`item`)\n    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Twink Master vendor item categories';\n\n    INSERT INTO `custom_twinkmaster_vendor_categories` (`item`, `categories`) VALUES\n    -- =============================================\n    -- BiS Gear (cat=1) - Equipment only\n    -- =============================================\n    -- Weapons (melee)\n    (1482,  1),  -- Shadowfang\n    (5191,  1),  -- Cruel Barb\n    (1935,  1),  -- Assassin's Blade\n    (6448,  1),  -- Tail Spike\n    (1483,  1),  -- Face Smasher\n    (6472,  1),  -- Stinging Viper\n    (6504,  1),  -- Wingblade\n    (7230,  1),  -- Smite's Mighty Hammer\n    (5815,  1),  -- Glacial Stone\n    (890,   1),  -- Twisted Chanter's Staff\n    (6505,  1),  -- Crescent Staff\n    (1484,  1),  -- Witching Stave\n    (5201,  1),  -- Emberstone Staff\n    (2271,  1),  -- Staff of the Blessed Seer\n    (1318,  1),  -- Night Reaver (2H Axe, shadow proc)\n    (2256,  1),  -- Skeletal Club (1H Mace, shadow proc)\n    (5196,  1),  -- Smite's Reaver (1H axe)\n    (2567,  1),  -- Evocator's Blade (caster dagger)\n    (935,   1),  -- Night Watch Shortsword (caster sword)\n    (790,   1),  -- Forester's Axe (1H axe, Paladin)\n    -- Weapons (ranged/wand)\n    (6469,  1),  -- Venomstrike\n    (13136, 1),  -- Lil Timmy's Peashooter\n    (7001,  1),  -- Gravestone Scepter\n    -- Head\n    (19972, 1),  -- Lucky Fishing Hat\n    (4385,  1),  -- Green Tinted Goggles\n    -- Shoulders\n    (5404,  1),  -- Serpent's Shoulders\n    (10657, 1),  -- Talbar Mantle\n    (6579,  1),  -- Defender Spaulders (random enchant)\n    -- Back\n    (2059,  1),  -- Sentry Cloak\n    (6449,  1),  -- Glowing Lizardscale Cloak\n    (6667,  1),  -- Engineer's Cloak\n    -- Chest\n    (10399, 1),  -- Blackened Defias Armor\n    (2041,  1),  -- Tunic of Westfall\n    (1486,  1),  -- Tree Bark Jacket\n    (6473,  1),  -- Armor of the Fang\n    -- Wrist\n    (1974,  1),  -- Mindthrust Bracers\n    (4534,  1),  -- Steel-clasped Bracers\n    (15331, 1),  -- Wrangler's Wristbands (random enchant)\n    (7003,  1),  -- Beetle Clasps (mail)\n    (3202,  1),  -- Forest Leather Bracers\n    (14160, 1),  -- Pagan Bands (cloth, random enchant)\n    -- Hands\n    (6467,  1),  -- Deviate Scale Gloves\n    (10413, 1),  -- Gloves of the Fang\n    (12977, 1),  -- Magefist Gloves\n    (892,   1),  -- Gnoll Casting Gloves\n    (6586,  1),  -- Scouting Gloves (random enchant)\n    (12994, 1),  -- Thorbia's Gauntlets (mail)\n    (6577,  1),  -- Defender Gauntlets (mail, random enchant)\n    -- Waist\n    (6468,  1),  -- Deviate Scale Belt\n    (10412, 1),  -- Belt of the Fang\n    (6460,  1),  -- Cobrahn's Grasp\n    (9814,  1),  -- Fortified Belt (mail, random enchant)\n    (2911,  1),  -- Keller's Girdle (cloth)\n    (16987, 1),  -- Screecher Belt (leather)\n    -- Legs\n    (6087,  1),  -- Chausses of Westfall\n    (10410, 1),  -- Leggings of the Fang\n    (12987, 1),  -- Darkweave Breeches\n    (15511, 1),  -- Grunt's Legguards (mail, random enchant)\n    (6587,  1),  -- Scouting Trousers (leather, random enchant)\n    (4800,  1),  -- Mighty Chain Pants (mail)\n    (10043, 1),  -- Pious Legwraps (cloth, Alliance quest)\n    -- Feet\n    (1121,  1),  -- Feet of the Lynx\n    (19969, 1),  -- Nat Pagle's Extreme Anglin' Boots\n    (12982, 1),  -- Silver-linked Footguards\n    (10411, 1),  -- Footpads of the Fang\n    -- Rings\n    (2933,  1),  -- Seal of Wrynn\n    (6414,  1),  -- Seal of Sylvanas\n    (4998,  1),  -- Blood Ring\n    (12054, 1),  -- Demon Band\n    (1156,  1),  -- Lavishly Jeweled Ring\n    (12996, 1),  -- Band of Purification\n    (12006, 1),  -- Meadow Ring (random enchant)\n    -- Trinkets\n    (19024, 1),  -- Arena Grand Master\n    (4381,  1),  -- Minor Recombobulator\n    -- Shields\n    (5443,  1),  -- Gold-plated Buckler\n    (12997, 1),  -- Redbeard Crest\n    (7002,  1),  -- Arctic Buckler\n    (3761,  1),  -- Deadskull Shield\n    -- Off-hand\n    (2879,  1),  -- Antipodean Rod\n    (5183,  1),  -- Pulsating Hydra Heart\n    (16768, 1),  -- Furbolg Medicine Pouch\n    -- =============================================\n    -- Consumables (cat=2)\n    -- =============================================\n    -- Potions / Elixirs\n    (2459,  2),  -- Swiftness Potion\n    (3388,  2),  -- Strong Troll's Blood Potion\n    (2454,  2),  -- Elixir of Lion's Strength\n    (2455,  2),  -- Minor Mana Potion\n    (929,   2),  -- Healing Potion\n    (3390,  2),  -- Elixir of Lesser Agility\n    (3389,  2),  -- Elixir of Defense\n    (6373,  2),  -- Elixir of Firepower\n    (3384,  2),  -- Minor Magic Resistance Potion\n    (6372,  2),  -- Swim Speed Potion (WSG essential)\n    (5631,  2),  -- Rage Potion (+20-40 Rage, Warriors only)\n    (6051,  2),  -- Holy Protection Potion (absorb holy)\n    (2458,  2),  -- Elixir of Minor Fortitude (+27 HP, Guardian)\n    (3383,  2),  -- Elixir of Wisdom (+6 Int, Battle)\n    -- Scrolls\n    (1478,  2),  -- Scroll of Protection II\n    (3012,  2),  -- Scroll of Agility (+5 Agi)\n    (1180,  2),  -- Scroll of Stamina (+5 Stam)\n    (954,   2),  -- Scroll of Strength (+5 Str)\n    (2290,  2),  -- Scroll of Intellect II\n    -- Head/Leg Enchants (Lesser Arcanums - BRD)\n    (11642, 2),  -- Lesser Arcanum of Constitution (+100 HP)\n    (11622, 2),  -- Lesser Arcanum of Rumination (+150 Mana)\n    (11643, 2),  -- Lesser Arcanum of Tenacity (+125 Armor)\n    (11644, 2),  -- Lesser Arcanum of Resilience (+20 Fire Resist)\n    (11645, 2),  -- Lesser Arcanum of Voracity (+8 Str)\n    (11646, 2),  -- Lesser Arcanum of Voracity (+8 Agi)\n    (11647, 2),  -- Lesser Arcanum of Voracity (+8 Stam)\n    (11648, 2),  -- Lesser Arcanum of Voracity (+8 Int)\n    (11649, 2),  -- Lesser Arcanum of Voracity (+8 Spi)\n    -- Head/Leg Enchants (Arcanums - Dire Maul)\n    (18329, 2),  -- Arcanum of Rapidity (+1% Haste)\n    (18330, 2),  -- Arcanum of Focus (+8 Spell Power)\n    (18331, 2),  -- Arcanum of Protection (+1% Dodge)\n    -- Drinks (stamina buffs)\n    (21151, 2),  -- Rumsey Rum Black Label (+15 Stam)\n    (18269, 2),  -- Gordok Green Grog (+10 Stam)\n    -- Transformation / Fun\n    (6657,  2),  -- Savory Deviate Delight (pirate/ninja)\n    (6662,  2),  -- Elixir of Giant Growth (size increase)\n    (6522,  2),  -- Deviate Fish (random effects)\n    -- Engineering gadgets\n    (4388,  2),  -- Discombobulator Ray (transform + slow)\n    (4380,  2),  -- Big Bronze Bomb (AoE stun)\n    (4378,  2),  -- Heavy Dynamite (AoE damage)\n    (4384,  2),  -- Explosive Sheep (mobile AoE)\n    (4376,  2),  -- Flame Deflector (absorb fire)\n    (4366,  2),  -- Target Dummy (attracts mobs, no Eng req)\n    (6714,  2),  -- EZ-Thro Dynamite (AoE, no Eng req)\n    -- PvP utility\n    (2091,  2),  -- Magic Dust (sleep target)\n    (4984,  2),  -- Skull of Impending Doom (speed boost)\n    (13180, 2),  -- Stratholme Holy Water (AoE vs undead)\n    (7676,  2),  -- Thistle Tea (instant 100 energy)\n    -- Food buffs\n    (3665,  2),  -- Curiously Tasty Omelet\n    (6890,  2),  -- Smoked Bear Meat\n    -- Weapon buffs\n    (4406,  2),  -- Standard Scope (+2 damage)\n    (10548, 2),  -- Sniper Scope (+7 damage)\n    (2871,  2),  -- Heavy Sharpening Stone (+4 weapon damage)\n    (2863,  2),  -- Coarse Sharpening Stone (+3 weapon damage)\n    (20744, 2),  -- Minor Wizard Oil (+8 Spell Damage)\n    (1322,  2),  -- Fishliver Oil (+8 melee AP)\n    -- Ammo\n    (3464,  2),  -- Feathered Arrow\n    (3465,  2),  -- Exploding Shot\n    -- Bandages\n    (6451,  2),  -- Heavy Silk Bandage (First Aid 125)\n    (8544,  2),  -- Mageweave Bandage (First Aid 150)\n    -- Utility\n    (6048,  2),  -- Shadow Protection Potion (level 17)\n    (3241,  2),  -- Heavy Weightstone (+4 blunt weapon dmg)\n    (1712,  2),  -- Scroll of Spirit II\n    -- =============================================\n    -- Honor Gear (cat=3) - PvP / WSG reputation items\n    -- =============================================\n    -- PvP accessories (rings, trinkets, medallions)\n    (20444, 3),  -- Sentinel's Medallion\n    (20442, 3),  -- Scout's Medallion\n    (20439, 3),  -- Protector's Band\n    (20429, 3),  -- Legionnaire's Band\n    (20431, 3),  -- Lorekeeper's Ring\n    (20426, 3),  -- Advisor's Ring\n    (18854, 3),  -- Insignia of the Alliance\n    (18834, 3),  -- Insignia of the Horde\n    -- Class-specific insignias (Alliance)\n    (18856, 3),  -- Insignia of the Alliance (Hunter)\n    (18857, 3),  -- Insignia of the Alliance (Rogue)\n    (18858, 3),  -- Insignia of the Alliance (Warlock)\n    (18859, 3),  -- Insignia of the Alliance (Mage)\n    (18862, 3),  -- Insignia of the Alliance (Priest)\n    (18863, 3),  -- Insignia of the Alliance (Druid)\n    (18864, 3),  -- Insignia of the Alliance (Paladin)\n    -- Class-specific insignias (Horde)\n    (18845, 3),  -- Insignia of the Horde (Shaman)\n    (18846, 3),  -- Insignia of the Horde (Hunter)\n    (18849, 3),  -- Insignia of the Horde (Rogue)\n    (18850, 3),  -- Insignia of the Horde (Mage)\n    (18851, 3),  -- Insignia of the Horde (Priest)\n    (18852, 3),  -- Insignia of the Horde (Warlock)\n    (18853, 3),  -- Insignia of the Horde (Druid)\n    -- Battle Standards\n    (18606, 3),  -- Alliance Battle Standard\n    (18607, 3),  -- Horde Battle Standard\n    -- Tabards\n    (15196, 3),  -- Private's Tabard (Alliance)\n    (15197, 3),  -- Scout's Tabard (Horde)\n    (19506, 3),  -- Silverwing Battle Tabard (Alliance WSG)\n    (19505, 3),  -- Warsong Battle Tabard (Horde WSG)\n    -- WSG reputation weapons and cloaks\n    (20425, 3),  -- Advisor's Gnarled Staff\n    (20427, 3),  -- Battle Healer's Cloak\n    (20428, 3),  -- Caretaker's Cape\n    (20430, 3),  -- Legionnaire's Sword\n    (20434, 3),  -- Lorekeeper's Staff\n    (20437, 3),  -- Outrider's Bow\n    (20438, 3),  -- Outrunner's Bow\n    (20440, 3),  -- Protector's Sword\n    (20441, 3),  -- Scout's Blade\n    (20443, 3),  -- Sentinel's Blade\n    -- =============================================\n    -- Insane (cat=4) - Raid/endgame items with no level req\n    -- =============================================\n    -- Trinkets\n    (23206, 4),  -- Mark of the Champion (melee)\n    (23207, 4),  -- Mark of the Champion (caster)\n    (18406, 4),  -- Onyxia Blood Talisman\n    (19948, 4),  -- Zandalarian Hero Badge\n    (19949, 4),  -- Zandalarian Hero Medallion\n    (19950, 4),  -- Zandalarian Hero Charm\n    (21180, 4),  -- Earthstrike\n    (21326, 4),  -- Defender of the Timbermaw\n    (22678, 4),  -- Talisman of Ascendance\n    (17904, 4),  -- Stormpike Insignia Rank 6\n    (17909, 4),  -- Frostwolf Insignia Rank 6\n    -- Rings\n    (18403, 4),  -- Dragonslayer's Signet\n    (22707, 4),  -- Ramaladni's Icy Grasp\n    (21189, 4),  -- Might of Cenarius\n    (21190, 4),  -- Wrath of Cenarius\n    -- Necklaces\n    (18404, 4),  -- Onyxia Tooth Pendant\n    (22657, 4),  -- Amulet of the Dawn\n    (22659, 4),  -- Medallion of the Dawn\n    (19577, 4),  -- Rage of Mugamba\n    (19588, 4),  -- Hero's Brand\n    (19594, 4),  -- The All-Seeing Eye of Zuldazar\n    (19601, 4),  -- Jewel of Kajaro\n    (19605, 4),  -- Kezan's Unstoppable Taint\n    (19609, 4),  -- Unmarred Vision of Voodress\n    (19613, 4),  -- Pristine Enchanted South Seas Kelp\n    (19617, 4),  -- Zandalarian Shadow Mastery Talisman\n    (19621, 4),  -- Maelstrom's Wrath\n    -- Cloth armor (no level req, raid)\n    (22968, 4),  -- Glacial Mantle\n    (22700, 4),  -- Glacial Leggings\n    (12752, 4),  -- Cap of the Scarlet Savant\n    -- Off-hand\n    (21185, 4),  -- Earthcalm Orb\n    -- Weapon\n    (22656, 4),  -- The Purifier\n    -- Shoulder Enchants (ZG, no level req)\n    (20077, 4),  -- Zandalar Signet of Might (+30 AP)\n    (20076, 4),  -- Zandalar Signet of Mojo (+18 SP)\n    (20078, 4),  -- Zandalar Signet of Serenity (+33 Healing)\n    -- Shoulder Enchants (Naxx, level req removed below)\n    (23545, 4),  -- Power of the Scourge (+15 SP, +1% Spell Crit)\n    (23547, 4),  -- Resilience of the Scourge (+31 Healing, +5 MP5)\n    (23548, 4),  -- Might of the Scourge (+26 AP, +1% Crit)\n    (23549, 4),  -- Fortitude of the Scourge (+16 Stam, +100 Armor)\n    -- Bags\n    (17966, 4);  -- Onyxia Hide Backpack (18 slot)\n\n    -- ============================================================\n    -- Remove level requirements from Naxx shoulder enchants\n    -- so they are usable at level 19 (Insane category)\n    -- ============================================================\n    UPDATE `item_template` SET `RequiredLevel` = 0\n    WHERE `entry` IN (23545, 23547, 23548, 23549);\n\n    -- ============================================================\n    -- Restore original prices if previously zeroed, then drop backup\n    -- ============================================================\n    SET @tbl_exists = (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'custom_twinkmaster_original_prices');\n    SET @restore_sql = IF(@tbl_exists > 0,\n      'UPDATE `item_template` it JOIN `custom_twinkmaster_original_prices` op ON it.`entry` = op.`entry` SET it.`BuyPrice` = op.`original_buy_price`, it.`SellPrice` = op.`original_sell_price` WHERE it.`BuyPrice` = 0 AND op.`original_buy_price` > 0',\n      'SELECT 1');\n    PREPARE stmt FROM @restore_sql;\n    EXECUTE stmt;\n    DEALLOCATE PREPARE stmt;\n    DROP TABLE IF EXISTS `custom_twinkmaster_original_prices`;\n\n    -- ============================================================\n    -- NPC Vendor Inventory (for standard vendor fallback only;\n    -- category vendor uses custom SMSG_LIST_INVENTORY with price=0)\n    -- ============================================================\n    DELETE FROM `npc_vendor` WHERE `entry` IN (@AllianceEntry, @HordeEntry);\n\n    INSERT INTO `npc_vendor` (`entry`, `item`, `maxcount`, `incrtime`)\n    SELECT @AllianceEntry, `item`, 0, 0 FROM `custom_twinkmaster_vendor_categories`\n    UNION ALL\n    SELECT @HordeEntry, `item`, 0, 0 FROM `custom_twinkmaster_vendor_categories`;\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-twink-vendor-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Applying Twink Master schema to classiccharacters ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters < /sql/characters.sql\n              echo \"=== Characters schema applied successfully ===\"\n\n              echo \"=== Applying Twink Master data to classicmangos ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos < /sql/world.sql\n              echo \"=== World data applied successfully ===\"\n\n              echo \"=== Verifying characters table ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SHOW TABLES LIKE 'custom_twinkmaster%';\"\n\n              echo \"=== Verifying Twink Master NPCs ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, name, subname, faction, NpcFlags FROM creature_template WHERE entry IN (190012, 190013);\"\n\n              echo \"=== Verifying creature spawns ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT id, map, position_x, position_y, position_z FROM creature WHERE id IN (190012, 190013);\"\n\n              echo \"=== Verifying vendor items per entry ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT entry, COUNT(*) AS vendor_item_count FROM npc_vendor WHERE entry IN (190012, 190013) GROUP BY entry;\"\n\n              echo \"=== Verifying vendor categories ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"\n                SELECT\n                  CASE categories\n                    WHEN 1 THEN 'BiS Gear'\n                    WHEN 2 THEN 'Consumables'\n                    WHEN 3 THEN 'Honor Gear'\n                    WHEN 4 THEN 'Insane'\n                  END AS category,\n                  COUNT(*) AS item_count\n                FROM custom_twinkmaster_vendor_categories\n                GROUP BY categories\n                ORDER BY categories;\n              \"\n\n              echo \"=== Validating all vendor item IDs exist in item_template ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"\n                SELECT nv.entry, nv.item AS missing_item_id\n                FROM npc_vendor nv\n                LEFT JOIN item_template it ON nv.item = it.entry\n                WHERE nv.entry IN (190012, 190013) AND it.entry IS NULL;\n              \"\n\n              echo \"=== Twink Master vendor migration complete ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-twink-vendor-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/vip-master-spell-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-vip-master-spell-migration-sql\n  namespace: game-servers\ndata:\n  vip-master-spell.sql: |\n    -- VIP master spell migration: cleanup + existing-VIP swap.\n    --\n    -- We use vanilla spell 18282 'Dummy Spell' as the master (already\n    -- Effect1=SPELL_EFFECT_DUMMY in vanilla spell_template, exists in\n    -- the client's Spell.dbc, zero references in item/trainer/chain\n    -- tables). VipModule::OnCast hooks the cast and fires the cascade.\n    -- No INSERT/UPDATE on spell_template needed.\n    --\n    -- This script:\n    --   1) DELETEs the obsolete custom spell row 91200 we tried first\n    --      (vanilla 1.12 clients couldn't display it).\n    --   2) UPDATEs character_spell to swap 22888 (the v2 hot-fix master)\n    --      with 18282 for any existing VIPs. Rallying Cry of the\n    --      Dragonslayer is not legitimately learnable in vanilla — anyone\n    --      with it as a known spell got it from `.vip grant`, so the\n    --      swap is safe.\n    --\n    -- Canonical SQL: etc/emberstone/sql/world/vip-master-spell.sql in\n    -- xunholy/cmangos-classic. Keep in sync.\n    --\n    -- Idempotent on both statements.\n\n    DELETE FROM `classicmangos`.`spell_template` WHERE `Id` = 91200;\n    UPDATE `classiccharacters`.`character_spell` SET `spell` = 18282 WHERE `spell` = 22888;\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-vip-master-spell-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Cleanup obsolete spell 91200 + swap existing VIPs 22888 → 18282 ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" < /sql/vip-master-spell.sql\n              echo \"=== Verify cleanup ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicmangos -e \"SELECT COUNT(*) AS spell_91200_rows FROM spell_template WHERE Id = 91200;\"\n              echo \"=== Verify VIP migration ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classiccharacters -e \"SELECT spell, COUNT(*) AS chars FROM character_spell WHERE spell IN (22888, 18282) GROUP BY spell;\"\n              echo \"=== Done. Restart mangosd so the new Vip.MasterSpellId from the ConfigMap takes effect ===\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-vip-master-spell-migration-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: cmangos-database-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: cmangos-database-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cmangos\n  namespace: game-servers\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 10m\n  path: \"./apps/base/game-servers/cmangos/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: ExternalArtifact\n    name: cmangos\n    namespace: flux-system\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: game-servers\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/db-init-job.yaml",
    "content": "---\n# Seeds the PTR databases on the shared MariaDB. World DB is a full clone\n# of live so PTR has every NPC/quest/item/script the GMs would actually\n# want to test against. Characters + logs are schema-only so PTR\n# characters stay separate from live (the realm is GM-only via realmlist\n# allowedSecurityLevel=3 anyway).\n#\n# Idempotent: if ptrmangos already has a non-trivial table count, the\n# job exits 0 without touching anything. To force a fresh clone, drop\n# the ptr* databases and let Flux re-run the job.\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-ptr-db-init\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: init\n          image: mariadb:12.2\n          # CREATE DATABASE + GRANT must be run as root (the app user lacks\n          # global CREATE). Dumps + restores then run as root too, since\n          # we already have a root session here. App-user grants are what\n          # the runtime PTR mangosd actually needs — username from secret.\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          env:\n            - name: ROOT_PWD\n              value: password\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -euo pipefail\n              MARIADB=\"mariadb -h cmangos-database -P 3306 -u root -p$${ROOT_PWD}\"\n              DUMP=\"mariadb-dump -h cmangos-database -P 3306 -u root -p$${ROOT_PWD} --single-transaction --routines --triggers\"\n\n              already_seeded() {\n                local db=$1\n                local count\n                count=$($${MARIADB} -N -B -e \"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$${db}';\")\n                [ \"$${count}\" -gt 0 ]\n              }\n\n              echo \"=== Ensuring PTR databases exist ===\"\n              $${MARIADB} -e \"CREATE DATABASE IF NOT EXISTS ptrmangos     CHARACTER SET utf8 COLLATE utf8_general_ci;\"\n              $${MARIADB} -e \"CREATE DATABASE IF NOT EXISTS ptrcharacters CHARACTER SET utf8 COLLATE utf8_general_ci;\"\n              $${MARIADB} -e \"CREATE DATABASE IF NOT EXISTS ptrlogs       CHARACTER SET utf8 COLLATE utf8_general_ci;\"\n\n              echo \"=== Granting $${MANGOS_DBUSER}@% access to PTR databases ===\"\n              $${MARIADB} -e \"GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE ROUTINE, ALTER ROUTINE ON \\`ptrmangos\\`.* TO '$${MANGOS_DBUSER}'@'%';\"\n              $${MARIADB} -e \"GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON \\`ptrcharacters\\`.* TO '$${MANGOS_DBUSER}'@'%';\"\n              $${MARIADB} -e \"GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON \\`ptrlogs\\`.* TO '$${MANGOS_DBUSER}'@'%';\"\n              $${MARIADB} -e \"FLUSH PRIVILEGES;\"\n\n              if already_seeded ptrmangos; then\n                echo \"=== ptrmangos already populated, skipping world clone ===\"\n              else\n                echo \"=== Cloning classicmangos -> ptrmangos (full data) ===\"\n                $${DUMP} classicmangos | $${MARIADB} ptrmangos\n              fi\n\n              if already_seeded ptrcharacters; then\n                echo \"=== ptrcharacters already populated, skipping characters clone ===\"\n              else\n                echo \"=== Cloning classiccharacters -> ptrcharacters (schema + version row) ===\"\n                $${DUMP} --no-data classiccharacters | $${MARIADB} ptrcharacters\n                # mangosd refuses to boot without a row in *_db_version\n                # (compatibility check). Copy the live row so PTR runs\n                # against whatever schema rev live is on.\n                $${MARIADB} -e \"INSERT INTO ptrcharacters.character_db_version SELECT * FROM classiccharacters.character_db_version;\"\n              fi\n\n              if already_seeded ptrlogs; then\n                echo \"=== ptrlogs already populated, skipping logs clone ===\"\n              else\n                echo \"=== Cloning classiclogs -> ptrlogs (schema + version row) ===\"\n                $${DUMP} --no-data classiclogs | $${MARIADB} ptrlogs\n                $${MARIADB} -e \"INSERT INTO ptrlogs.logs_db_version SELECT * FROM classiclogs.logs_db_version;\"\n              fi\n\n              echo \"=== Done. Table counts: ===\"\n              for db in ptrmangos ptrcharacters ptrlogs; do\n                c=$($${MARIADB} -N -B -e \"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$${db}';\")\n                echo \"  $${db}: $${c} tables\"\n              done\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\n#\n# Emberstone PTR — mangosd-only worldserver.\n#\n# Auth and the MariaDB live in the cmangos HelmRelease and are shared\n# with the live realm. PTR has its own world/characters/logs databases\n# (ptrmangos/ptrcharacters/ptrlogs) on the same MariaDB instance, and\n# is gated to GM (security >= 3) accounts via realmlist.allowedSecurityLevel.\n# Realm id is 2 (live is 1).\n#\n# Compute is sized for \"a handful of GMs poking at content,\" not live\n# load — half the live mangosd footprint.\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: cmangos-ptr\n  namespace: game-servers\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      mangosd:\n        pod:\n          terminationGracePeriodSeconds: 180\n        initContainers:\n          wait-db:\n            image:\n              repository: busybox\n              tag: latest\n            command: ['sh', '-c', 'until nc -z cmangos-database 3306; do sleep 2; done']\n        containers:\n          app:\n            image:\n              repository: ghcr.io/xunholy/cmangos-classic\n              tag: 2473619f4ff3431fe68bacec5b05fa52fa0e0fba\n            args: [\"mangosd\"]\n            tty: true\n            stdin: true\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              MANGOS_DBHOST: cmangos-database\n              MANGOS_DBPORT: \"3306\"\n              # Auth DB is shared with live so accounts/GM flags carry over.\n              MANGOS_REALMD_DBNAME: classicrealmd\n              # Game state isolated from live.\n              MANGOS_WORLD_DBNAME: ptrmangos\n              MANGOS_CHARACTERS_DBNAME: ptrcharacters\n              MANGOS_LOGS_DBNAME: ptrlogs\n            envFrom:\n              # MANGOS_DBUSER + MANGOS_DBPASS from 1Password via ESO —\n              # shared with live (same MariaDB instance, cmangos_app has\n              # grants on ptrmangos / ptrcharacters / ptrlogs and the\n              # shared classicrealmd). Hardcoded mangos:mangos was left\n              # over from before the rotation; the old PTR pod survived\n              # only because it held a pre-rotation DB connection.\n              - secretRef:\n                  name: cmangos-database-creds\n            # Matches live's graceful-shutdown pattern, tightened for PTR:\n            # 120s in-game countdown + 140s drain, SIGTERM at ~160s, SIGKILL\n            # at 180s. PTR will rarely have anyone logged in so a shorter\n            # window keeps rollouts snappy.\n            lifecycle:\n              preStop:\n                exec:\n                  command:\n                    - /bin/sh\n                    - -c\n                    - |\n                      echo \"server restart 120\" > /tmp/mangosd-stdin\n                      sleep 140\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8086\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8086\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8086\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 180\n            resources:\n              requests:\n                cpu: \"1\"\n                memory: 2Gi\n              limits:\n                memory: 6Gi\n          # Tail GM audit log to stdout — same pattern as live so GM\n          # actions on PTR are visible in kubectl logs and any future\n          # log collector.\n          gm-log-tail:\n            image:\n              repository: busybox\n              tag: latest\n            command:\n              - /bin/sh\n              - -c\n              - |\n                while [ ! -f /opt/mangos/logs/gm.log ]; do sleep 5; done\n                exec tail -F /opt/mangos/logs/gm.log\n            resources:\n              requests:\n                cpu: 5m\n                memory: 8Mi\n              limits:\n                memory: 32Mi\n            securityContext:\n              runAsUser: 1001\n              runAsGroup: 1001\n              runAsNonRoot: true\n              readOnlyRootFilesystem: true\n              allowPrivilegeEscalation: false\n              capabilities:\n                drop: [\"ALL\"]\n          # Cores-pruner — same UID + cap reasoning as live. Keeps the\n          # 20Gi PTR cores PVC from wedging if PTR ever enters a crash loop.\n          cores-pruner:\n            image:\n              repository: busybox\n              tag: latest\n            command:\n              - /bin/sh\n              - -c\n              - |\n                while true; do\n                  if cd /opt/mangos/cores 2>/dev/null; then\n                    find . -maxdepth 1 -name 'core.*' -size 0 -delete 2>/dev/null\n                    # shellcheck disable=SC2012\n                    ls -1t core.* 2>/dev/null | tail -n +3 | xargs -r rm -f --\n                  fi\n                  sleep 600\n                done\n            resources:\n              requests:\n                cpu: 5m\n                memory: 8Mi\n              limits:\n                memory: 32Mi\n            securityContext:\n              runAsUser: 1001\n              runAsGroup: 1001\n              runAsNonRoot: true\n              readOnlyRootFilesystem: true\n              allowPrivilegeEscalation: false\n              capabilities:\n                drop: [\"ALL\"]\n    service:\n      world:\n        controller: mangosd\n        ports:\n          world:\n            port: 8086\n      soap:\n        controller: mangosd\n        ports:\n          soap:\n            # Different cluster-internal port than live so the two SOAP\n            # endpoints don't collide if anything ever cross-references.\n            port: 7879\n    configMaps:\n      mangosd-config:\n        data:\n          mangosd.conf: |\n            RealmID = 2\n            GameType = 1\n            RealmZone = 8\n            WorldServerPort = 8086\n            BindIP = \"0.0.0.0\"\n            # Tight cap — PTR is for GM smoke tests, not live load.\n            PlayerLimit = 50\n            MapUpdate.Threads = 1\n            Motd = \"Welcome to Emberstone PTR — GM-only test realm\"\n            LogLevel = 3\n            LogFile = \"/opt/mangos/logs/Server.log\"\n            LogFileLevel = 3\n            LogTimestamp = 1\n            GmLogFile = \"/opt/mangos/logs/gm.log\"\n            GmLogTimestamp = 1\n            GmLogPerAccount = 0\n            LogGMTrade = 1\n            LogFilter_GMChat = 0\n            SOAP.Enabled = 1\n            SOAP.IP = 0.0.0.0\n            SOAP.Port = 7879\n            Rate.XP.Kill = 1\n            Rate.XP.Quest = 1\n            Rate.XP.Explore = 1\n            Rate.Drop.Item.Poor = 3\n            Rate.Drop.Item.Normal = 3\n            Rate.Drop.Item.Uncommon = 3\n            Rate.Drop.Item.Rare = 2\n            Rate.Drop.Item.Epic = 1\n            Rate.Drop.Money = 3\n            Rate.Reputation.Gain = 3\n            AllowTwoSide.Interaction.Group = 1\n            AllowTwoSide.Interaction.Guild = 1\n            AllowTwoSide.Interaction.Chat = 1\n            AllowTwoSide.Interaction.Channel = 1\n            MailDeliveryDelay = 0\n            StartPlayerMoney = 100000\n            SkillGain.Crafting = 3\n            SkillGain.Gathering = 3\n            SkillGain.Defense = 3\n            SkillGain.Weapon = 3\n            Rate.Drop.Item.Quest = 3\n            Death.Ghost.RunSpeed.World = 1.5\n            PlayerSaveInterval = 60000\n            Rate.Health = 3\n            Rate.Mana = 3\n      # All side-modules kept enabled so GMs can test the same feature\n      # surface as live. PlayerBots is the only module disabled — no\n      # aiplayerbot.conf is mounted, the module no-ops without config.\n      hardcore-config:\n        data:\n          hardcore.conf: |\n            Hardcore.Enable = 1\n            Hardcore.PlayerConfig = 1\n            Hardcore.BroadcastDeathGuild = 1\n            Hardcore.BroadcastDeathWorld = 1\n            Hardcore.SpawnGrave = 1\n            Hardcore.GraveGameObjectID = 61\n            Hardcore.GraveMessage = \"PTR death. <PlayerName>\"\n            Hardcore.RemoveGravesOnCharacterDeleted = 1\n            Hardcore.DropGear = 0\n            Hardcore.DropItems = 0\n            Hardcore.DropMoney = 0\n            Hardcore.BotDropGear = 0\n            Hardcore.BotDropItems = 0\n            Hardcore.BotDropMoney = 0\n            Hardcore.RemoveLootOnCharacterDeleted = 1\n            Hardcore.LootGameObjectID = 2850\n            Hardcore.ReviveDisabled = 1\n            Hardcore.ReviveOnGraveyard = 0\n            Hardcore.LevelDown = 0\n            Hardcore.MaxPlayerLoot = 99\n            Hardcore.DropOnDungeons = 1\n            Hardcore.DropOnRaids = 1\n            Hardcore.LevelDownOnDungeons = 1\n            Hardcore.LevelDownOnRaids = 1\n            Hardcore.LevelDownMinLevel = 1\n            Hardcore.DropMinLevel = 1\n            Hardcore.DisablePVP = 0\n            Hardcore.SelfFound = 0\n            Hardcore.CustomXPRates = 0\n      twinkmaster-config:\n        data:\n          twinkmaster.conf: |\n            Twinkmaster.Enable = 1\n            Twinkmaster.TargetLevel = 19\n      attunement-config:\n        data:\n          attunement.conf: |\n            Attunement.Enable = 1\n            Attunement.DefaultRate = 1.0\n            Attunement.MinRate = 0.1\n            Attunement.MaxRate = 100\n            Attunement.Aura.Tier1.SpellId = 0\n            Attunement.Aura.Tier2.SpellId = 0\n            Attunement.Aura.Tier3.SpellId = 0\n            Attunement.Aura.Tier4.SpellId = 0\n            Attunement.Aura.Tier5.SpellId = 0\n      anticheat-config:\n        data:\n          anticheat.conf: |\n            [AnticheatConf]\n            ConfVersion=2017102301\n            Enable = 1\n            FingerprintHistory = 30\n            FingerprintLevel = 6\n            KickDelay.Min = 30\n            KickDelay.Max = 90\n            BanDelay.Min = 30\n            BanDelay.Max = 90\n            IPBanDelay.Min = 30\n            IPBanDelay.Max = 90\n            BanWave.Day = 1\n            BanWave.Hour = 10\n            BanWave.Minute = 0\n            Movement.UseExtrapolation = 1\n            Movement.SpeedHack.Enable  = 1\n            Movement.WallClimb.TickCount   = 0\n            Movement.WallClimb.TickAction  = 0\n            Movement.WallClimb.TotalCount  = 0\n            Movement.WallClimb.TotalAction = 0\n            Movement.WaterWalk.TickCount   = 1\n            Movement.WaterWalk.TickAction  = 7\n            Movement.WaterWalk.TotalCount  = 0\n            Movement.WaterWalk.TotalAction = 0\n            Movement.SlowFall.TickCount   = 1\n            Movement.SlowFall.TickAction  = 7\n            Movement.SlowFall.TotalCount  = 0\n            Movement.SlowFall.TotalAction = 0\n            Movement.FlyHack.TickCount    = 1\n            Movement.FlyHack.TickAction   = 7\n            Movement.FlyHack.TotalCount   = 0\n            Movement.FlyHack.TotalAction  = 0\n            Movement.Forbidden.TickCount  = 1\n            Movement.Forbidden.TickAction = 7\n            Movement.Forbidden.TotalCount = 0\n            Movement.Forbidden.TotalAction= 0\n            Movement.NullClientTime.TickCount  = 1\n            Movement.NullClientTime.TickAction = 7\n            Movement.NullClientTime.TotalCount = 0\n            Movement.NullClientTime.TotalAction = 0\n            Movement.RootMove.TickCount  = 1\n            Movement.RootMove.TickAction = 7\n            Movement.RootMove.TotalCount = 0\n            Movement.RootMove.TotalAction= 0\n            Movement.TimeBack.TickCount  = 1\n            Movement.TimeBack.TickAction = 7\n            Movement.TimeBack.TotalCount = 0\n            Movement.TimeBack.TotalAction= 0\n            Movement.FakeTransport.TickCount   = 1\n            Movement.FakeTransport.TickAction  = 7\n            Movement.FakeTransport.TotalCount  = 0\n            Movement.FakeTransport.TotalAction = 0\n            Movement.TeleToTransport.TickCount  = 1\n            Movement.TeleToTransport.TickAction = 7\n            Movement.TeleToTransport.TotalCount = 0\n            Movement.TeleToTransport.TotalAction= 0\n            Movement.FixedZ.TickCount  = 1\n            Movement.FixedZ.TickAction = 7\n            Movement.FixedZ.TotalCount = 0\n            Movement.FixedZ.TotalAction= 0\n            Movement.MultiJump.TickCount    = 1\n            Movement.MultiJump.TickAction   = 3\n            Movement.MultiJump.TotalCount   = 10\n            Movement.MultiJump.TotalAction  = 7\n            Movement.FastJump.TickCount     = 1\n            Movement.FastJump.TickAction    = 3\n            Movement.FastJump.TotalCount    = 10\n            Movement.FastJump.TotalAction   = 7\n            Movement.JumpSpeedChange.TickCount  = 1\n            Movement.JumpSpeedChange.TickAction = 3\n            Movement.JumpSpeedChange.TotalCount = 10\n            Movement.JumpSpeedChange.TotalAction= 7\n            Movement.HeartbeatSkip.TickCount  = 1\n            Movement.HeartbeatSkip.TickAction = 3\n            Movement.HeartbeatSkip.TotalCount = 10\n            Movement.HeartbeatSkip.TotalAction= 7\n            Movement.ClockDesync.TickCount  = 1\n            Movement.ClockDesync.TickAction = 3\n            Movement.ClockDesync.TotalCount = 10\n            Movement.ClockDesync.TotalAction= 7\n            Movement.OverspeedZ.TickCount   = 1\n            Movement.OverspeedZ.TickAction  = 3\n            Movement.OverspeedZ.TotalCount  = 5\n            Movement.OverspeedZ.TotalAction = 7\n            Movement.BadOrderAck.TickCount  = 1\n            Movement.BadOrderAck.TickAction = 3\n            Movement.BadOrderAck.TotalCount = 5\n            Movement.BadOrderAck.TotalAction= 7\n            Movement.Teleport.TickCount     = 1\n            Movement.Teleport.TickAction    = 7\n            Movement.Teleport.TotalCount    = 0\n            Movement.Teleport.TotalAction   = 0\n            Movement.TeleportFar.TickCount  = 1\n            Movement.TeleportFar.TickAction = 7\n            Movement.TeleportFar.TotalCount = 0\n            Movement.TeleportFar.TotalAction= 0\n            Movement.Explore.TickCount     = 3\n            Movement.Explore.TickAction    = 3\n            Movement.Explore.TotalCount    = 0\n            Movement.Explore.TotalAction   = 0\n            Movement.ExploreHigh.TickCount  = 1\n            Movement.ExploreHigh.TickAction = 3\n            Movement.ExploreHigh.TotalCount  = 0\n            Movement.ExploreHigh.TotalAction = 0\n            Movement.BadFallReset.Enable    = 1\n            Movement.BadFallReset.Threshold = 1\n            Movement.BadFallReset.Penalty   = 7\n            Antispam.Enable   = 1\n            Antispam.Silence  = 1\n            Antispam.MaxLevel = 25\n            Warden.Enable                       = 1\n            Warden.ModuleDir                    = \"/opt/mangos/bin/warden_modules\"\n            Warden.Timeout                      = 30\n            Warden.ScanFrequency                = 15\n            Warden.ScanCount                    = 10\n            Warden.MinimumLevel                 = 1\n            Warden.MinimumAdvancedLevel         = 1\n            Warden.SuspiciousEndSceneHookAction = 7\n            Warden.TickCount                    = 1\n            Warden.TickAction                   = 7\n            Warden.TotalCount                   = 0\n            Warden.TotalAction                  = 0\n      vip-config:\n        data:\n          vip.conf: |\n            Vip.Enable = 1\n            Vip.MasterSpellId = 22888\n            Vip.BundledSpellIds = \"\"\n      autoscale-config:\n        data:\n          autoscale.conf: |\n            Autoscale.Enable = 1\n            Autoscale.RescanIntervalSeconds = 10\n            Autoscale.HpExponent = 0.85\n            Autoscale.MinScale = 0.20\n            Autoscale.MaxScale = 1.0\n            Autoscale.Baseline.Dungeon = 5\n            Autoscale.Baseline.RaidDefault = 40\n            Autoscale.MapBaselines = \"309:20,509:20\"\n            Autoscale.MapBlacklist = \"\"\n            Autoscale.Announce = 1\n      ahbot-config:\n        data:\n          ahbot.conf: |\n            AuctionHouseBot.Seller.Enabled = 1\n            AuctionHouseBot.Buyer.Enabled = 1\n            AuctionHouseBot.Chance.Sell = 80\n            AuctionHouseBot.Chance.Buy = 40\n            AuctionHouseBot.Alliance.Items.Amount.Ratio = 100\n            AuctionHouseBot.Horde.Items.Amount.Ratio = 100\n            AuctionHouseBot.Neutral.Items.Amount.Ratio = 80\n            AuctionHouseBot.Buy.Value = 90\n            AuctionHouseBot.Bid.Min = 60\n            AuctionHouseBot.Bid.Max = 95\n            AuctionHouseBot.Time.Min = 2\n            AuctionHouseBot.Time.Max = 48\n            AuctionHouseBot.Value.Variance = 15\n            AuctionHouseBot.Items.Profession = 90, 100, 0, 60\n            AuctionHouseBot.Loot.Creature.Normal = 40, 50, 8, 15\n            AuctionHouseBot.Loot.Creature.Elite = 35, 40, 2, 4\n            AuctionHouseBot.Loot.Creature.Rare = 5, 15, 1, 2\n            AuctionHouseBot.Loot.Disenchant = 15, 20, 1, 3\n            AuctionHouseBot.Loot.Fishing = 5, 10, 30, 50\n            AuctionHouseBot.Loot.Gameobject = 20, 25, 7, 15\n            AuctionHouseBot.Loot.Skinning = 5, 10, 50, 80\n    persistence:\n      data:\n        existingClaim: cmangos-ptr-data\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /var/lib/mangos\n                readOnly: true\n      cores:\n        existingClaim: cmangos-ptr-cores\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/cores\n            cores-pruner:\n              - path: /opt/mangos/cores\n      mangosd-config:\n        type: configMap\n        name: cmangos-ptr-mangosd-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/mangosd.conf\n                subPath: mangosd.conf\n      hardcore-config:\n        type: configMap\n        name: cmangos-ptr-hardcore-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/etc/hardcore.conf\n                subPath: hardcore.conf\n      twinkmaster-config:\n        type: configMap\n        name: cmangos-ptr-twinkmaster-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/twinkmaster.conf\n                subPath: twinkmaster.conf\n      attunement-config:\n        type: configMap\n        name: cmangos-ptr-attunement-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/attunement.conf\n                subPath: attunement.conf\n      anticheat-config:\n        type: configMap\n        name: cmangos-ptr-anticheat-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/anticheat.conf\n                subPath: anticheat.conf\n      vip-config:\n        type: configMap\n        name: cmangos-ptr-vip-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/vip.conf\n                subPath: vip.conf\n      autoscale-config:\n        type: configMap\n        name: cmangos-ptr-autoscale-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/autoscale.conf\n                subPath: autoscale.conf\n      ahbot-config:\n        type: configMap\n        name: cmangos-ptr-ahbot-config\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/conf/ahbot.conf\n                subPath: ahbot.conf\n      mangosd-logs:\n        existingClaim: cmangos-ptr-mangosd-logs\n        advancedMounts:\n          mangosd:\n            app:\n              - path: /opt/mangos/logs\n            gm-log-tail:\n              - path: /opt/mangos/logs\n                readOnly: true\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc-cores.yaml\n  - pvc-data.yaml\n  - pvc-logs.yaml\n  - tcproute.yaml\n  - db-init-job.yaml\n  - realm-row-migration-job.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/pvc-cores.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: cmangos-ptr-cores\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 20Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/pvc-data.yaml",
    "content": "---\n# CoW clone of the live cmangos-data PVC at PVC-creation time so PTR\n# gets its own copy of /var/lib/mangos (DBC + maps + vmaps + mmaps)\n# without competing for the live volume's ReadWriteOnce lock. Clone is\n# point-in-time; refreshing PTR data later means deleting and recreating\n# this PVC (Flux will reclone from current live state).\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: cmangos-ptr-data\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n  dataSource:\n    kind: PersistentVolumeClaim\n    name: cmangos-data\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/pvc-logs.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: cmangos-ptr-mangosd-logs\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/realm-row-migration-job.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cmangos-ptr-realm-row-sql\n  namespace: game-servers\ndata:\n  # realmlist.allowedSecurityLevel=2 = Game Master tier and above (GM +\n  # Admin). Regular players + Moderator-tier accounts see the realm\n  # greyed out in the launcher and the auth server rejects their connect\n  # attempt with \"Server is for higher level account.\" cmangos security\n  # tiers: 0=Player, 1=Moderator, 2=GM, 3=Admin.\n  # icon=1 (PvP) matches the live realm so the lobby badge agrees with\n  # mangosd.conf GameType=1. realmbuilds matches live (\"5875 6005 6141 \")\n  # so the same set of client builds are accepted. Same EXTERNAL_IP as\n  # live — clients route by port (8086 vs 8085).\n  realm-ptr.sql: |\n    INSERT INTO `realmlist`\n      (id, name, address, port, icon, realmflags, timezone,\n       allowedSecurityLevel, population, realmbuilds)\n    VALUES\n      (2, 'Emberstone PTR', '${EXTERNAL_IP}', 8086, 1, 0, 8,\n       2, 0, '5875 6005 6141 ')\n    ON DUPLICATE KEY UPDATE\n      name                 = VALUES(name),\n      address              = VALUES(address),\n      port                 = VALUES(port),\n      icon                 = VALUES(icon),\n      realmflags           = VALUES(realmflags),\n      timezone             = VALUES(timezone),\n      allowedSecurityLevel = VALUES(allowedSecurityLevel),\n      population           = VALUES(population),\n      realmbuilds          = VALUES(realmbuilds);\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: cmangos-ptr-realm-row-migration\n  namespace: game-servers\nspec:\n  ttlSecondsAfterFinished: 86400\n  backoffLimit: 3\n  template:\n    spec:\n      restartPolicy: Never\n      initContainers:\n        - name: wait-db\n          image: busybox:latest\n          command: ['sh', '-c', 'until nc -z cmangos-database 3306; do echo \"Waiting for database...\"; sleep 2; done']\n      containers:\n        - name: migrate\n          image: mariadb:12.2\n          envFrom:\n            - secretRef:\n                name: cmangos-database-creds\n          command:\n            - /bin/bash\n            - -c\n            - |\n              set -e\n              echo \"=== Upserting Emberstone PTR realmlist row (id=2) ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicrealmd < /sql/realm-ptr.sql\n              echo \"=== Verifying ===\"\n              mariadb -h cmangos-database -P 3306 -u \"$MANGOS_DBUSER\" -p\"$MANGOS_DBPASS\" classicrealmd \\\n                -e \"SELECT id, name, address, port, allowedSecurityLevel FROM realmlist ORDER BY id;\"\n          volumeMounts:\n            - name: sql-scripts\n              mountPath: /sql\n      volumes:\n        - name: sql-scripts\n          configMap:\n            name: cmangos-ptr-realm-row-sql\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/app/tcproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: cmangos-ptr-world\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: cmangos-world-ptr\n  rules:\n    - backendRefs:\n        - name: cmangos-ptr-world\n          port: 8086\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/cmangos-ptr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cmangos-ptr\n  namespace: game-servers\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 10m\n  path: \"./apps/base/game-servers/cmangos-ptr/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: ExternalArtifact\n    name: cmangos-ptr\n    namespace: flux-system\n  dependsOn:\n    - name: cmangos\n      namespace: game-servers\n  targetNamespace: game-servers\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/externalsecret-soap.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: cmangos-soap-creds\n  namespace: game-servers\nspec:\n  refreshInterval: 1h\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: cmangos-soap-creds\n    template:\n      data:\n        SOAP_USER: \"{{ .SOAP_USER }}\"\n        SOAP_PASSWORD: \"{{ .SOAP_PASSWORD }}\"\n  dataFrom:\n    - extract:\n        key: cmangos\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: emberstone-portal-captcha\n  namespace: game-servers\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: emberstone-portal-captcha\n    template:\n      data:\n        CAPTCHA_KEY: \"{{ .SITE_KEY }}\"\n        CAPTCHA_SECRET: \"{{ .SECRET_KEY }}\"\n  dataFrom:\n    - extract:\n        key: emberstone\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: emberstone-portal\n  namespace: game-servers\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      app:\n        containers:\n          app:\n            image:\n              repository: ghcr.io/xunholy/cmangos-registration\n              tag: da24e639b3b8e8366f792423399cb8ef0ca2f4b7\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n            envFrom:\n              - secretRef:\n                  name: emberstone-portal-captcha\n              # SOAP creds (cmangos GM service account) from 1Password\n              # via ESO. Replaces hardcoded soapadmin:soapadmin that\n              # used to live in config.php.\n              - secretRef:\n                  name: cmangos-soap-creds\n              # cmangos DB creds (MANGOS_DBUSER / MANGOS_DBPASS) from\n              # 1Password via ESO. Replaces hardcoded mangos:mangos in\n              # config.php — that user was deleted in 2534bce98 and the\n              # portal's server-status / registration / change-password\n              # flows all 500'd until config.php picked these up.\n              - secretRef:\n                  name: cmangos-database-creds\n            probes:\n              liveness:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /\n                    port: 80\n                  periodSeconds: 30\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /\n                    port: 80\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 3\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /\n                    port: 80\n                  periodSeconds: 10\n                  timeoutSeconds: 3\n                  failureThreshold: 30\n            resources:\n              requests:\n                cpu: 10m\n                memory: 64Mi\n              limits:\n                memory: 256Mi\n    defaultPodOptions:\n      securityContext:\n        fsGroup: 33\n        fsGroupChangePolicy: OnRootMismatch\n    service:\n      app:\n        controller: app\n        ports:\n          http:\n            port: 80\n    persistence:\n      config:\n        type: configMap\n        name: emberstone-portal-config\n        advancedMounts:\n          app:\n            app:\n              - path: /var/www/html/application/config/config.php\n                subPath: config.php\n              - path: /var/www/html/template/kaelthas/tpl/header.php\n                subPath: header.php\n              - path: /var/www/html/template/kaelthas/tpl/footer.php\n                subPath: footer.php\n              - path: /var/www/html/template/kaelthas/tpl/main.php\n                subPath: main.php\n              - path: /var/www/html/template/kaelthas/tpl/posts.php\n                subPath: posts.php\n              - path: /var/www/html/template/kaelthas/tpl/howtoconnect.php\n                subPath: howtoconnect.php\n              - path: /var/www/html/template/kaelthas/tpl/bot_filter.php\n                subPath: bot_filter.php\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: emberstone-portal\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'emberstone.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: emberstone-portal\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - externalsecret.yaml\n  - externalsecret-soap.yaml\n\nconfigMapGenerator:\n  - name: emberstone-portal-config\n    namespace: game-servers\n    files:\n      - config.php=./resources/config.php\n      - header.php=./resources/header.php\n      - footer.php=./resources/footer.php\n      - main.php=./resources/main.php\n      - posts.php=./resources/posts.php\n      - howtoconnect.php=./resources/howtoconnect.php\n      - bot_filter.php=./resources/bot_filter.php\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/values/persistence/config/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/resources/bot_filter.php",
    "content": "<?php\n/**\n * Emberstone Portal - Real-player filter\n *\n * The upstream user::/status:: classes in cmangos-registration include AI\n * Playerbot accounts in their online and top-player listings, which makes\n * the server-status and top-players tabs useless once random-bot autologin\n * is on (300-500 bots drown out real players).\n *\n * Each helper below mirrors the upstream query but adds a\n * `account NOT IN (<rndbot account ids>)` clause. Bot account ids are\n * looked up once per request from the auth DB (RandomBotAccountPrefix\n * defaults to \"rndbot\") and cached in a static variable.\n *\n * These names deliberately differ from the upstream (`portal_*` vs\n * `user::`/`status::`) so that a future upstream bump cannot silently\n * revert the filter — main.php has to be updated to opt in.\n */\n\n/**\n * Account ids of AI Playerbot accounts. Cached per request.\n * @return int[]\n */\nfunction portal_bot_account_ids()\n{\n    static $ids = null;\n    if ($ids === null) {\n        // LIKE 'RNDBOT%' with UPPER() to survive collation quirks. Matches the\n        // default AiPlayerbot.RandomBotAccountPrefix; if the admin changes\n        // that prefix, this filter stops working and bots reappear in the\n        // lists — make that the failure mode, not silent matching of the\n        // wrong accounts.\n        $ids = database::$auth->fetchFirstColumn(\n            \"SELECT id FROM account WHERE UPPER(username) LIKE 'RNDBOT%'\"\n        );\n    }\n    return $ids;\n}\n\n/**\n * Attach the bot-exclusion clause to a QueryBuilder that selects from\n * characters. No-op when there are no bot accounts.\n */\nfunction portal_apply_bot_filter($qb)\n{\n    $bots = portal_bot_account_ids();\n    if (!empty($bots)) {\n        $qb->andWhere('account NOT IN (:portalBotIds)')\n           ->setParameter('portalBotIds', $bots, \\Doctrine\\DBAL\\ArrayParameterType::INTEGER);\n    }\n    return $qb;\n}\n\nfunction portal_online_count($realm)\n{\n    $qb = database::$chars[$realm['realmid']]->createQueryBuilder()\n        ->select('COUNT(*)')\n        ->from('characters')\n        ->where('online = 1');\n    portal_apply_bot_filter($qb);\n    return (int) $qb->executeQuery()->fetchOne();\n}\n\nfunction portal_online_players($realm)\n{\n    $qb = database::$chars[$realm['realmid']]->createQueryBuilder()\n        ->select('name, race, class, gender, level')\n        ->from('characters')\n        ->where('online = 1')\n        ->orderBy('level', 'DESC')\n        ->setMaxResults(49);\n    portal_apply_bot_filter($qb);\n    $rows = $qb->executeQuery()->fetchAllAssociative();\n    return empty($rows[0]['name']) ? false : $rows;\n}\n\n/**\n * Real characters active in the past 30 days (online now or logged out\n * within the window), online-first and then most-recently-seen. Returns\n * raw `online` flag and `logout_time` so the view can render a\n * \"Last seen\" label.\n */\nfunction portal_recent_activity($realm, $windowSeconds = 2592000)\n{\n    $qb = database::$chars[$realm['realmid']]->createQueryBuilder()\n        ->select('name, race, class, gender, level, online, logout_time')\n        ->from('characters')\n        ->where('online = 1 OR logout_time >= :cutoff')\n        ->setParameter('cutoff', time() - $windowSeconds)\n        ->orderBy('online', 'DESC')\n        ->addOrderBy('logout_time', 'DESC')\n        ->setMaxResults(49);\n    portal_apply_bot_filter($qb);\n    $rows = $qb->executeQuery()->fetchAllAssociative();\n    return empty($rows[0]['name']) ? false : $rows;\n}\n\n/**\n * Highest-level real character on the realm (all-time, not restricted to\n * the recent-activity window — the point is bragging rights). Returns a\n * single row or false.\n */\nfunction portal_highest_level_char($realm)\n{\n    $qb = database::$chars[$realm['realmid']]->createQueryBuilder()\n        ->select('name, race, class, gender, level')\n        ->from('characters')\n        ->orderBy('level', 'DESC')\n        ->addOrderBy('totaltime', 'DESC')\n        ->setMaxResults(1);\n    portal_apply_bot_filter($qb);\n    $rows = $qb->executeQuery()->fetchAllAssociative();\n    return empty($rows[0]['name']) ? false : $rows[0];\n}\n\n/**\n * Render a short \"Last seen\" label for a character row with `online`\n * and `logout_time` fields. Pure formatter — no DB access.\n */\nfunction portal_format_last_seen($row)\n{\n    if (!empty($row['online'])) {\n        return 'Online now';\n    }\n    $ago = max(0, time() - (int) ($row['logout_time'] ?? 0));\n    if ($ago < 60) {\n        return 'just now';\n    }\n    if ($ago < 3600) {\n        return floor($ago / 60) . 'm ago';\n    }\n    if ($ago < 86400) {\n        return floor($ago / 3600) . 'h ago';\n    }\n    return floor($ago / 86400) . 'd ago';\n}\n\nfunction portal_top_playtime($realm)\n{\n    $qb = database::$chars[$realm['realmid']]->createQueryBuilder()\n        ->select('name, race, class, gender, level, totaltime')\n        ->from('characters')\n        ->orderBy('totaltime', 'DESC')\n        ->setMaxResults(10);\n    portal_apply_bot_filter($qb);\n    $rows = $qb->executeQuery()->fetchAllAssociative();\n    return empty($rows[0]['totaltime']) ? false : $rows;\n}\n\nfunction portal_top_killers($realm)\n{\n    $conn = database::$chars[$realm['realmid']];\n    // AzerothCore-style schema (totalKills column).\n    try {\n        $qb = $conn->createQueryBuilder()\n            ->select('name, race, class, gender, level, totalKills')\n            ->from('characters')\n            ->orderBy('totalKills', 'DESC')\n            ->setMaxResults(10);\n        portal_apply_bot_filter($qb);\n        $rows = $qb->executeQuery()->fetchAllAssociative();\n        // Query succeeded — schema is AzerothCore. Don't fall through to\n        // the CMaNGOS-only column even if no real player has any kills,\n        // otherwise stored_honorable_kills will throw on AzerothCore.\n        return empty($rows[0]['totalKills']) ? false : $rows;\n    } catch (\\Exception $e) {\n        // CMaNGOS Classic: totalKills column doesn't exist; fall through.\n    }\n    // CMaNGOS Classic schema (stored_honorable_kills column).\n    try {\n        $qb = $conn->createQueryBuilder()\n            ->select('name, race, class, gender, level, stored_honorable_kills as totalKills')\n            ->from('characters')\n            ->orderBy('stored_honorable_kills', 'DESC')\n            ->setMaxResults(10);\n        portal_apply_bot_filter($qb);\n        $rows = $qb->executeQuery()->fetchAllAssociative();\n        return empty($rows[0]['totalKills']) ? false : $rows;\n    } catch (\\Exception $e) {\n        return false;\n    }\n}\n\nfunction portal_top_honorpoints($realm)\n{\n    $conn = database::$chars[$realm['realmid']];\n    // AzerothCore / Classic-Era schema (totalHonorPoints / honorLevel+honor).\n    try {\n        $qb = $conn->createQueryBuilder();\n        if (get_config('expansion') >= 6) {\n            $qb->select('name, race, class, gender, level, honorLevel, honor')\n               ->from('characters')\n               ->orderBy('honorLevel', 'DESC')\n               ->addOrderBy('honor', 'DESC')\n               ->setMaxResults(10);\n        } else {\n            $qb->select('name, race, class, gender, level, totalHonorPoints')\n               ->from('characters')\n               ->orderBy('totalHonorPoints', 'DESC')\n               ->setMaxResults(10);\n        }\n        portal_apply_bot_filter($qb);\n        $rows = $qb->executeQuery()->fetchAllAssociative();\n        // Query succeeded — schema fits. Don't fall through to the\n        // CMaNGOS-only column even if no real player has honor; otherwise\n        // stored_honor_rating will throw on AzerothCore.\n        return empty($rows[0]['level']) ? false : $rows;\n    } catch (\\Exception $e) {\n        // CMaNGOS Classic: totalHonorPoints column doesn't exist; fall through.\n    }\n    // CMaNGOS Classic schema (stored_honor_rating column).\n    try {\n        $qb = $conn->createQueryBuilder()\n            ->select('name, race, class, gender, level, stored_honor_rating as totalHonorPoints')\n            ->from('characters')\n            ->orderBy('stored_honor_rating', 'DESC')\n            ->setMaxResults(10);\n        portal_apply_bot_filter($qb);\n        $rows = $qb->executeQuery()->fetchAllAssociative();\n        return empty($rows[0]['level']) ? false : $rows;\n    } catch (\\Exception $e) {\n        return false;\n    }\n}\n\nfunction portal_top_arenapoints($realm)\n{\n    try {\n        $qb = database::$chars[$realm['realmid']]->createQueryBuilder()\n            ->select('name, race, class, gender, level, arenaPoints')\n            ->from('characters')\n            ->orderBy('arenaPoints', 'DESC')\n            ->setMaxResults(10);\n        portal_apply_bot_filter($qb);\n        $rows = $qb->executeQuery()->fetchAllAssociative();\n        return empty($rows[0]['arenaPoints']) ? false : $rows;\n    } catch (\\Exception $e) {\n        return false;\n    }\n}\n\n/**\n * Arena teams don't store account directly; filter by captain character.\n * Fetch a wider slice (20 teams) so the post-filter has a decent chance\n * of still returning 10 real entries when bot captains dominate the top.\n */\nfunction portal_top_arenateams($realm)\n{\n    try {\n        $qb = database::$chars[$realm['realmid']]->createQueryBuilder()\n            ->select('arenaTeamId, name, captainGuid, rating')\n            ->from('arena_team')\n            ->orderBy('rating', 'DESC')\n            ->setMaxResults(20);\n        $teams = $qb->executeQuery()->fetchAllAssociative();\n    } catch (\\Exception $e) {\n        return false;\n    }\n    if (empty($teams)) {\n        return false;\n    }\n\n    $bots = portal_bot_account_ids();\n    if (empty($bots)) {\n        return array_slice($teams, 0, 10);\n    }\n\n    $captainGuids = array_values(array_filter(array_column($teams, 'captainGuid')));\n    if (empty($captainGuids)) {\n        return array_slice($teams, 0, 10);\n    }\n\n    $guidQb = database::$chars[$realm['realmid']]->createQueryBuilder()\n        ->select('guid')\n        ->from('characters')\n        ->where('guid IN (:guids)')\n        ->andWhere('account NOT IN (:bots)')\n        ->setParameter('guids', $captainGuids, \\Doctrine\\DBAL\\ArrayParameterType::INTEGER)\n        ->setParameter('bots', $bots, \\Doctrine\\DBAL\\ArrayParameterType::INTEGER);\n    $realCaptainGuids = array_flip($guidQb->executeQuery()->fetchFirstColumn());\n\n    $filtered = array_values(array_filter(\n        $teams,\n        fn($t) => isset($realCaptainGuids[$t['captainGuid']])\n    ));\n    return empty($filtered) ? false : array_slice($filtered, 0, 10);\n}\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/resources/config.php",
    "content": "<?php\n/**\n * Emberstone Portal - Multi-Expansion Configuration\n *\n * Each expansion defines its own database, server core, theme, and content.\n * The selected expansion overrides the global $config before loader.php\n * processes core_handler.php and database.php, so all downstream code\n * (SRP6, registration, status) works unchanged.\n */\n\n// ── Expansion Definitions ───────────────────────────────────────────────────\n$expansions = [\n    'vanilla' => [\n        'label'          => 'Classic (1.12.1)',\n        'page_title'     => 'Emberstone',\n        'game_version'   => '1.12.1',\n        'expansion'      => '0',\n        'server_core'    => 5, // CMaNGOS: s/v fields, reversed salt in SRP6\n        'realmlist'      => 'wow.owncloud.ai',\n        'soap_host'      => 'cmangos-soap',\n        'soap_port'      => '7878',\n        'soap_uri'       => 'urn:MaNGOS',\n        'db_auth_host'   => 'cmangos-database',\n        'db_auth_port'   => '3306',\n        // DB creds from 1Password via cmangos-database-creds ESO (envFrom\n        // in helmrelease). The previous hardcoded mangos:mangos user was\n        // deleted in commit 2534bce98; empty fallback so a missing env\n        // fails loudly (Access denied) rather than silently retrying the\n        // dead user.\n        'db_auth_user'   => getenv('MANGOS_DBUSER') ?: '',\n        'db_auth_pass'   => getenv('MANGOS_DBPASS') ?: '',\n        'db_auth_dbname' => 'classicrealmd',\n        'realmlists'     => [\n            '1' => [\n                'realmid'   => 1,\n                'realmname' => 'Emberstone',\n                'db_host'   => 'cmangos-database',\n                'db_port'   => '3306',\n                'db_user'   => getenv('MANGOS_DBUSER') ?: '',\n                'db_pass'   => getenv('MANGOS_DBPASS') ?: '',\n                'db_name'   => 'classiccharacters',\n            ],\n        ],\n        'theme' => [\n            'gold'          => '#C9A84C',\n            'gold_bright'   => '#E8D48B',\n            'gold_dark'     => '#8B6B1A',\n            'gold_muted'    => '#A08A4E',\n            'gold_glow'     => 'rgba(201, 168, 76, 0.5)',\n            'gold_dim'      => 'rgba(201, 168, 76, 0.07)',\n            'border'        => 'rgba(201, 168, 76, 0.08)',\n            'border_hover'  => 'rgba(201, 168, 76, 0.20)',\n            'border_active' => 'rgba(201, 168, 76, 0.40)',\n            'particle_rgb'  => '201, 168, 76',\n        ],\n        'hero_logo'   => 'wow-classic-logo.png',\n        'hero_badge'  => 'Classic',\n        'hero_sub'    => 'Return to the world as it was meant to be. A Classic World of Warcraft realm with faithful 1.12.1 mechanics, authentic content progression, and a dedicated community.',\n        'bg_glow_css' => '',\n        'hero_filter' => '',\n    ],\n    'wotlk' => [\n        'label'          => 'Wrath of the Lich King (3.3.5a)',\n        'page_title'     => 'Emberstone',\n        'game_version'   => '3.3.5a',\n        'expansion'      => '2',\n        'server_core'    => 1, // AzerothCore: salt/verifier fields\n        'realmlist'      => 'wow.owncloud.ai:3725',\n        'soap_host'      => 'azerothcore-soap',\n        'soap_port'      => '7878',\n        'soap_uri'       => 'urn:AC',\n        'db_auth_host'   => 'azerothcore-database',\n        'db_auth_port'   => '3306',\n        'db_auth_user'   => 'root',\n        'db_auth_pass'   => 'password',\n        'db_auth_dbname' => 'acore_auth',\n        'realmlists'     => [\n            '1' => [\n                'realmid'   => 1,\n                'realmname' => 'Emberstone',\n                'db_host'   => 'azerothcore-database',\n                'db_port'   => '3306',\n                'db_user'   => 'root',\n                'db_pass'   => 'password',\n                'db_name'   => 'acore_characters',\n            ],\n        ],\n        'theme' => [\n            'gold'          => '#7CB9E8',\n            'gold_bright'   => '#B3D9F7',\n            'gold_dark'     => '#1B5E8A',\n            'gold_muted'    => '#5A9DC4',\n            'gold_glow'     => 'rgba(124, 185, 232, 0.5)',\n            'gold_dim'      => 'rgba(124, 185, 232, 0.07)',\n            'border'        => 'rgba(124, 185, 232, 0.08)',\n            'border_hover'  => 'rgba(124, 185, 232, 0.20)',\n            'border_active' => 'rgba(124, 185, 232, 0.40)',\n            'particle_rgb'  => '124, 185, 232',\n        ],\n        'hero_logo'   => 'wow-logo.png',\n        'hero_badge'  => 'Wrath of the Lich King',\n        'hero_sub'    => 'The Lich King awaits. A Wrath of the Lich King realm with 5x rates, AI companions, solo dungeons, and every quality-of-life feature to make your adventure legendary.',\n        'bg_glow_css' => 'radial-gradient(ellipse 800px 600px at 25% 20%, rgba(56, 140, 204, 0.06) 0%, transparent 70%), radial-gradient(ellipse 600px 800px at 75% 80%, rgba(100, 60, 180, 0.05) 0%, transparent 70%), radial-gradient(ellipse 1200px 400px at 50% 50%, rgba(124, 185, 232, 0.03) 0%, transparent 60%)',\n        'hero_filter' => 'hue-rotate(190deg) saturate(1.4) brightness(0.85)',\n    ],\n];\n\n// ── Expansion Selection (GET > POST > cookie > default) ─────────────────────\n$default_expansion = 'vanilla';\n$selected_expansion = $default_expansion;\n\nif (!empty($_GET['expansion']) && isset($expansions[$_GET['expansion']])) {\n    $selected_expansion = $_GET['expansion'];\n} elseif (!empty($_POST['expansion']) && isset($expansions[$_POST['expansion']])) {\n    $selected_expansion = $_POST['expansion'];\n} elseif (!empty($_COOKIE['selected_expansion']) && isset($expansions[$_COOKIE['selected_expansion']])) {\n    $selected_expansion = $_COOKIE['selected_expansion'];\n}\n\nsetcookie('selected_expansion', $selected_expansion, time() + 86400 * 30, '/');\n\n// ── Shared Config (same across all expansions) ──────────────────────��───────\n$config['baseurl']                = 'https://emberstone.owncloud.ai';\n$config['language']               = 'english';\n$config['supported_langs']        = ['english' => 'English'];\n$config['debug_mode']             = false;\n$config['patch_location']         = '';\n$config['battlenet_support']      = false;\n$config['srp6_support']           = true;\n$config['srp6_version']           = 0;\n$config['template']               = 'kaelthas';\n$config['captcha_type']           = 3;\n$config['captcha_key']            = getenv('CAPTCHA_KEY') ?: '';\n$config['captcha_secret']         = getenv('CAPTCHA_SECRET') ?: '';\n$config['captcha_language']       = 'en';\n$config['soap_for_register']      = false;\n$config['soap_style']             = 'SOAP_RPC';\n// SOAP creds come from ExternalSecret cmangos-soap-creds, mounted via\n// envFrom on the portal container. See externalsecret-soap.yaml.\n$config['soap_username']          = getenv('SOAP_USER') ?: '';\n$config['soap_password']          = getenv('SOAP_PASSWORD') ?: '';\n$config['soap_ca_command']        = 'account create {USERNAME} {PASSWORD}';\n$config['smtp_host']              = '';\n$config['smtp_port']              = 587;\n$config['smtp_auth']              = false;\n$config['smtp_user']              = '';\n$config['smtp_pass']              = '';\n$config['smtp_secure']            = 'tls';\n$config['smtp_mail']              = '';\n$config['vote_system']            = false;\n$config['vote_sites']             = [];\n$config['2fa_support']            = false;\n$config['soap_2d_command']        = 'account set 2fa {USERNAME} off';\n$config['soap_2e_command']        = 'account set 2fa {USERNAME} {SECRET}';\n$config['disable_changepassword'] = true;\n$config['disable_top_players']    = false;\n$config['disable_online_players'] = false;\n$config['multiple_email_use']     = true;\n$config['script_version']         = '2.0.4';\n\n// ── Override config with selected expansion ─��───────────────────────────────\n$exp = $expansions[$selected_expansion];\n$override_keys = [\n    'page_title', 'game_version', 'expansion', 'server_core', 'realmlist',\n    'soap_host', 'soap_port', 'soap_uri',\n    'db_auth_host', 'db_auth_port', 'db_auth_user', 'db_auth_pass', 'db_auth_dbname',\n    'realmlists',\n];\nforeach ($override_keys as $key) {\n    $config[$key] = $exp[$key];\n}\n\n// Expose expansion metadata for templates\n$config['_expansions']       = $expansions;\n$config['_selected']         = $selected_expansion;\n$config['_expansion_theme']  = $exp['theme'];\n$config['_expansion_meta']   = $exp;\n\n// ── Unified registration helper ─────────────────────────────────────────────\n// Computes SRP6 salt+verifier for a specific core type and returns values\n// ready for DB insertion (hex strings for CMaNGOS, binary for AzerothCore).\nfunction portal_compute_srp6($username, $password, $server_core) {\n    $g = gmp_init(7);\n    $N = gmp_init('894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7', 16);\n    $salt = random_bytes(32);\n    $h1 = sha1(strtoupper($username . ':' . $password), true);\n    if ($server_core == 5) {\n        $h2 = sha1(strrev($salt) . $h1, true);\n    } else {\n        $h2 = sha1($salt . $h1, true);\n    }\n    $h2 = gmp_import($h2, 1, GMP_LSW_FIRST);\n    $verifier = gmp_powm($g, $h2, $N);\n    $verifier = str_pad(gmp_export($verifier, 1, GMP_LSW_FIRST), 32, chr(0), STR_PAD_RIGHT);\n    if ($server_core == 5) {\n        return ['salt' => strtoupper(bin2hex($salt)), 'verifier' => strtoupper(bin2hex($verifier)), 'salt_field' => 's', 'verifier_field' => 'v'];\n    }\n    return ['salt' => $salt, 'verifier' => $verifier, 'salt_field' => 'salt', 'verifier_field' => 'verifier'];\n}\n\n// Creates account in a specific expansion's auth DB. Returns true on success.\nfunction portal_create_mirror_account($exp_config, $username, $password, $email) {\n    $conn = \\Doctrine\\DBAL\\DriverManager::getConnection([\n        'dbname' => $exp_config['db_auth_dbname'],\n        'user'   => $exp_config['db_auth_user'],\n        'password' => $exp_config['db_auth_pass'],\n        'host'   => $exp_config['db_auth_host'],\n        'port'   => $exp_config['db_auth_port'],\n        'driver' => 'pdo_mysql',\n        'charset' => 'utf8',\n    ], new \\Doctrine\\DBAL\\Configuration());\n    // Skip if account already exists\n    $existing = $conn->createQueryBuilder()\n        ->select('id')->from('account')\n        ->where('username = :u')->setParameter('u', strtoupper($username))\n        ->executeQuery()->fetchOne();\n    if ($existing) {\n        $conn->close();\n        return false;\n    }\n    $srp = portal_compute_srp6($username, $password, $exp_config['server_core']);\n    $conn->insert('account', [\n        'username'                  => strtoupper($username),\n        $srp['salt_field']          => $srp['salt'],\n        $srp['verifier_field']      => $srp['verifier'],\n        'email'                     => strtoupper($email),\n        'expansion'                 => $exp_config['expansion'],\n    ]);\n    $conn->close();\n    return true;\n}\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/resources/footer.php",
    "content": "<?php\n/**\n * Emberstone Portal - Footer Template\n * Particle and rune colors driven by expansion theme.\n */\n$theme = get_config('_expansion_theme');\n$rgb   = $theme['particle_rgb'];\n?>\n<div class=\"section-divider\"></div>\n<footer class=\"site-footer\">\n    <div class=\"footer-inner\">\n        <div class=\"footer-left\">Emberstone &middot; For the Horde &middot; For the Alliance</div>\n        <div class=\"footer-right\">\n            <?php echo (new SebastianBergmann\\Timer\\ResourceUsageFormatter)->resourceUsageSinceStartOfRequest(); ?>\n        </div>\n    </div>\n</footer>\n</div><!-- /.container -->\n</div><!-- /.content1 -->\n\n<script>\n/* Fix modals trapped inside .content1 stacking context (z-index:10) */\n$(document).on('show.bs.modal', '.modal', function() {\n    $(this).appendTo('body');\n});\n\n/* Custom navbar */\n(function() {\n    var nav = document.getElementById('site-nav');\n    var toggle = document.getElementById('nav-toggle');\n    var mobile = document.getElementById('nav-mobile');\n\n    window.addEventListener('scroll', function() {\n        nav.classList.toggle('scrolled', window.scrollY > 40);\n    }, {passive: true});\n\n    toggle.addEventListener('click', function() {\n        var open = mobile.classList.toggle('open');\n        toggle.classList.toggle('open', open);\n    });\n\n    window.closeMobileNav = function() {\n        mobile.classList.remove('open');\n        toggle.classList.remove('open');\n    };\n})();\n\n/* Smooth scroll to content section */\nwindow.scrollToContent = function() {\n    setTimeout(function() {\n        var el = document.getElementById('nav-tabContent');\n        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });\n    }, 150);\n};\n\n/* Particle canvas - color driven by expansion theme */\n(function() {\n    var c = document.getElementById('arcane-canvas');\n    if (!c) return;\n    var ctx = c.getContext('2d');\n    var w, h, particles = [], runeAngle = 0;\n    var RGB = '<?php echo $rgb; ?>';\n\n    function resize() {\n        w = c.width = window.innerWidth;\n        h = c.height = window.innerHeight;\n    }\n    resize();\n    window.addEventListener('resize', resize);\n\n    function Particle() { this.reset(); }\n    Particle.prototype.reset = function() {\n        this.x = Math.random() * w;\n        this.y = h + Math.random() * 100;\n        this.size = Math.random() * 2.5 + 0.5;\n        this.speedY = -(Math.random() * 0.6 + 0.15);\n        this.speedX = (Math.random() - 0.5) * 0.3;\n        this.opacity = Math.random() * 0.5 + 0.1;\n        this.life = 0;\n        this.maxLife = Math.random() * 400 + 200;\n    };\n    Particle.prototype.update = function() {\n        this.x += this.speedX + Math.sin(this.life * 0.008) * 0.15;\n        this.y += this.speedY;\n        this.life++;\n        var progress = this.life / this.maxLife;\n        this.currentOpacity = this.opacity * (progress < 0.1 ? progress / 0.1 : progress > 0.8 ? (1 - progress) / 0.2 : 1);\n        if (this.life >= this.maxLife || this.y < -20) this.reset();\n    };\n    Particle.prototype.draw = function() {\n        ctx.beginPath();\n        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n        ctx.fillStyle = 'rgba(' + RGB + ', ' + this.currentOpacity + ')';\n        ctx.fill();\n        if (this.size > 1.5) {\n            ctx.beginPath();\n            ctx.arc(this.x, this.y, this.size * 3, 0, Math.PI * 2);\n            ctx.fillStyle = 'rgba(' + RGB + ', ' + (this.currentOpacity * 0.12) + ')';\n            ctx.fill();\n        }\n    };\n\n    for (var i = 0; i < 80; i++) {\n        var p = new Particle();\n        p.life = Math.random() * p.maxLife;\n        p.y = Math.random() * h;\n        particles.push(p);\n    }\n\n    function drawRune(cx, cy, radius, angle) {\n        ctx.save();\n        ctx.translate(cx, cy);\n        ctx.rotate(angle);\n        ctx.beginPath();\n        ctx.arc(0, 0, radius, 0, Math.PI * 2);\n        ctx.strokeStyle = 'rgba(' + RGB + ', 0.06)';\n        ctx.lineWidth = 1.5;\n        ctx.stroke();\n        ctx.beginPath();\n        ctx.arc(0, 0, radius * 0.72, 0, Math.PI * 2);\n        ctx.strokeStyle = 'rgba(' + RGB + ', 0.04)';\n        ctx.lineWidth = 1;\n        ctx.stroke();\n        for (var i = 0; i < 8; i++) {\n            var a = (Math.PI * 2 / 8) * i;\n            ctx.beginPath();\n            ctx.moveTo(Math.cos(a) * radius * 0.72, Math.sin(a) * radius * 0.72);\n            ctx.lineTo(Math.cos(a) * radius, Math.sin(a) * radius);\n            ctx.strokeStyle = 'rgba(' + RGB + ', 0.05)';\n            ctx.lineWidth = 1;\n            ctx.stroke();\n        }\n        for (var j = 0; j < 4; j++) {\n            var a2 = (Math.PI * 2 / 4) * j + Math.PI / 4;\n            ctx.save();\n            ctx.translate(Math.cos(a2) * radius * 0.86, Math.sin(a2) * radius * 0.86);\n            ctx.rotate(a2);\n            ctx.beginPath();\n            ctx.moveTo(0, -4); ctx.lineTo(3, 0); ctx.lineTo(0, 4); ctx.lineTo(-3, 0);\n            ctx.closePath();\n            ctx.fillStyle = 'rgba(' + RGB + ', 0.08)';\n            ctx.fill();\n            ctx.restore();\n        }\n        ctx.restore();\n    }\n\n    function animate() {\n        requestAnimationFrame(animate);\n        ctx.clearRect(0, 0, w, h);\n        runeAngle += 0.001;\n        drawRune(w / 2, h * 0.38, Math.min(w, h) * 0.28, runeAngle);\n        drawRune(w / 2, h * 0.38, Math.min(w, h) * 0.20, -runeAngle * 1.4);\n        for (var i = 0; i < particles.length; i++) {\n            particles[i].update();\n            particles[i].draw();\n        }\n    }\n    animate();\n})();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/resources/header.php",
    "content": "<?php\n/**\n * Emberstone Portal - Header Template\n * Dynamic theming based on selected expansion.\n */\n$theme    = get_config('_expansion_theme');\n$meta     = get_config('_expansion_meta');\n$selected = get_config('_selected');\n$allExp   = get_config('_expansions');\n?>\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"<?php echo $antiXss->xss_clean(get_config(\"page_title\")); ?>\">\n    <title><?php echo $antiXss->xss_clean(get_config(\"page_title\")); ?></title>\n    <link rel=\"icon\" href=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/favicon.ico\" type=\"image/x-icon\">\n    <link rel=\"stylesheet\"\n          href=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/css/bootstrap.min.css\">\n    <link rel=\"stylesheet\"\n          href=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/css/bootsnav.css\">\n    <link rel=\"stylesheet\"\n          href=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/css/animate.css\">\n    <link href=\"https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css\" rel=\"stylesheet\"\n          integrity=\"sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN\" crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\"\n          href=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/css/style.css\">\n    <script src=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/js/jquery-3.3.1.min.js\"></script>\n    <script src=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/js/bootstrap.min.js\"></script>\n    <script src=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/js/bootsnav.js\"></script>\n    <script src=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/js/popper.min.js\"></script>\n    <?php echo getCaptchaJS(); ?>\n\n    <?php echo(!empty(lang('custom_css')) ? '<style>' . lang('custom_css') . '</style>' : ''); ?>\n\n    <style>\n    /* ── Mobile polish (overlay-only, no Docker rebuild) ─────────────── */\n    /* Belt-and-braces: never let the document overflow horizontally so\n       the fixed-position nav (and its right-aligned hamburger) can't end\n       up off-screen because of a stray child element. */\n    html, body {\n        overflow-x: hidden;\n        max-width: 100%;\n    }\n    *, *::before, *::after {\n        box-sizing: border-box;\n    }\n\n    /* Long words / URLs break instead of forcing horizontal scroll */\n    body, .post-card p, .connect-steps p, .box1 p, .box1 li {\n        overflow-wrap: break-word;\n        word-wrap: break-word;\n    }\n    code {\n        word-break: break-word;\n        white-space: normal;\n    }\n    /* Tables get a horizontal scrollbar instead of breaking the page */\n    .box1 .table-responsive,\n    .box1 table {\n        max-width: 100%;\n        overflow-x: auto;\n        -webkit-overflow-scrolling: touch;\n    }\n    img {\n        max-width: 100%;\n        height: auto;\n    }\n\n    /* Tablet (768-991): allow the 3 hero buttons to wrap onto two lines */\n    @media (max-width: 991px) {\n        .hero-actions {\n            flex-wrap: wrap;\n        }\n        pre.realmlist-block {\n            font-size: 1rem;\n            padding: 14px 18px;\n        }\n        /* Keep the navbar fully inside the viewport so the hamburger\n           sits at the right edge instead of past it */\n        .site-nav,\n        .site-nav.scrolled {\n            padding-left: 14px;\n            padding-right: 14px;\n        }\n        .nav-inner {\n            max-width: 100%;\n            width: 100%;\n        }\n    }\n\n    /* Mobile (<768): tighten paddings + stack inline button rows */\n    @media (max-width: 767px) {\n        .connect-steps a.btn,\n        .connect-steps .btn {\n            margin: 6px 0 !important;\n            margin-left: 0 !important;\n            width: 100%;\n            justify-content: center;\n        }\n        .hero-realm {\n            font-size: 0.85rem;\n            line-height: 1.5;\n            word-break: break-word;\n        }\n        .hero-realm strong {\n            display: inline-block;\n        }\n        pre.realmlist-block {\n            font-size: 0.9rem;\n            padding: 12px 14px;\n            white-space: pre-wrap;\n            word-break: break-all;\n        }\n        .modal-dialog {\n            margin: 8px;\n            max-width: calc(100% - 16px);\n        }\n        .post-card {\n            padding: 18px;\n        }\n        /* Form controls full-width on phones */\n        .input-group input,\n        .input-group select,\n        input[type=\"text\"],\n        input[type=\"email\"],\n        input[type=\"password\"] {\n            max-width: 100%;\n            box-sizing: border-box;\n        }\n    }\n    </style>\n    <!-- Dynamic expansion theme overrides -->\n    <style>\n    :root {\n        --gold: <?php echo $theme['gold']; ?>;\n        --gold-bright: <?php echo $theme['gold_bright']; ?>;\n        --gold-dark: <?php echo $theme['gold_dark']; ?>;\n        --gold-muted: <?php echo $theme['gold_muted']; ?>;\n        --gold-glow: <?php echo $theme['gold_glow']; ?>;\n        --gold-dim: <?php echo $theme['gold_dim']; ?>;\n        --border: <?php echo $theme['border']; ?>;\n        --border-hover: <?php echo $theme['border_hover']; ?>;\n        --border-active: <?php echo $theme['border_active']; ?>;\n    }\n    <?php if (!empty($meta['bg_glow_css'])) { ?>\n    .bg-glow { background: <?php echo $meta['bg_glow_css']; ?>; }\n    <?php } ?>\n    <?php if (!empty($meta['hero_filter'])) { ?>\n    .hero::before { filter: <?php echo $meta['hero_filter']; ?>; }\n    <?php } ?>\n    .expansion-select {\n        background: rgba(0,0,0,0.3);\n        border: 1px solid <?php echo $theme['border_hover']; ?>;\n        color: <?php echo $theme['gold_bright']; ?>;\n        padding: 4px 8px;\n        border-radius: 4px;\n        font-size: 0.85em;\n        cursor: pointer;\n        outline: none;\n    }\n    .expansion-select:hover,\n    .expansion-select:focus {\n        border-color: <?php echo $theme['gold']; ?>;\n    }\n    .expansion-select option {\n        background: #1a1a2e;\n        color: #e0e0e0;\n    }\n    </style>\n</head>\n<body>\n\n<!-- Arcane canvas background -->\n<canvas id=\"arcane-canvas\"></canvas>\n<div class=\"bg-glow\"></div>\n<div class=\"grain-overlay\"></div>\n\n<div class=\"content1\">\n    <!-- Fixed navbar -->\n    <nav class=\"site-nav\" id=\"site-nav\">\n        <div class=\"nav-inner\">\n            <a class=\"nav-logo\" href=\"./index.php\"><?php echo $antiXss->xss_clean(get_config(\"page_title\")); ?></a>\n            <button class=\"nav-toggle\" id=\"nav-toggle\" aria-label=\"Toggle menu\">\n                <span></span><span></span><span></span>\n            </button>\n            <ul class=\"nav-links\" id=\"nav-links\">\n                <li>\n                    <select class=\"expansion-select\" onchange=\"window.location.href='?expansion='+this.value\">\n                        <?php foreach ($allExp as $key => $exp_item) { ?>\n                            <option value=\"<?php echo htmlspecialchars($key); ?>\" <?php echo $selected === $key ? 'selected' : ''; ?>>\n                                <?php echo htmlspecialchars($exp_item['label']); ?>\n                            </option>\n                        <?php } ?>\n                    </select>\n                </li>\n                <li><a href=\"./index.php\">Home</a></li>\n                <li><a onclick=\"$('#register').trigger('click'); scrollToContent();\">Register</a></li>\n                <li><a onclick=\"$('#howtoconnect').trigger('click'); scrollToContent();\">Connect</a></li>\n                <?php if (!get_config('disable_online_players')) { ?>\n                    <li><a onclick=\"$('#serverstatus').trigger('click'); scrollToContent();\"><?php elang('server_status'); ?></a></li>\n                <?php }\n                if (!get_config('disable_top_players')) { ?>\n                    <li><a onclick=\"$('#topplayers').trigger('click'); scrollToContent();\"><?php elang('top_players'); ?></a></li>\n                <?php } ?>\n                <li><a href=\"https://discord.gg/quUmkgb5sD\" target=\"_blank\" rel=\"noopener noreferrer\">Discord</a></li>\n            </ul>\n        </div>\n    </nav>\n    <div class=\"nav-mobile\" id=\"nav-mobile\">\n        <select class=\"expansion-select\" style=\"margin: 8px 0; width: 100%;\" onchange=\"window.location.href='?expansion='+this.value\">\n            <?php foreach ($allExp as $key => $exp_item) { ?>\n                <option value=\"<?php echo htmlspecialchars($key); ?>\" <?php echo $selected === $key ? 'selected' : ''; ?>>\n                    <?php echo htmlspecialchars($exp_item['label']); ?>\n                </option>\n            <?php } ?>\n        </select>\n        <a href=\"./index.php\">Home</a>\n        <a onclick=\"$('#register').trigger('click'); closeMobileNav(); scrollToContent();\">Register</a>\n        <a onclick=\"$('#howtoconnect').trigger('click'); closeMobileNav(); scrollToContent();\">Connect</a>\n        <?php if (!get_config('disable_online_players')) { ?>\n            <a onclick=\"$('#serverstatus').trigger('click'); closeMobileNav(); scrollToContent();\"><?php elang('server_status'); ?></a>\n        <?php }\n        if (!get_config('disable_top_players')) { ?>\n            <a onclick=\"$('#topplayers').trigger('click'); closeMobileNav(); scrollToContent();\"><?php elang('top_players'); ?></a>\n        <?php } ?>\n        <a href=\"https://discord.gg/quUmkgb5sD\" target=\"_blank\" rel=\"noopener noreferrer\">Discord</a>\n    </div>\n\n    <!-- Also keep a hidden bootsnav navbar so Bootstrap tab JS still works -->\n    <nav class=\"navbar navbar-default bootsnav\" style=\"display:none !important;\">\n        <div class=\"collapse navbar-collapse\"><ul class=\"nav navbar-nav\"></ul></div>\n    </nav>\n\n    <div class=\"container\">\n        <!-- Hero -->\n        <section class=\"hero\">\n            <div class=\"hero-card\">\n                <img class=\"hero-wow-logo\" src=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/template/<?php echo $antiXss->xss_clean(get_config(\"template\")); ?>/images/<?php echo htmlspecialchars($meta['hero_logo']); ?>\" alt=\"World of Warcraft\">\n                <div class=\"hero-badge\">\n                    <span class=\"pulse-dot\"></span>\n                    <?php echo htmlspecialchars($meta['hero_badge']); ?> &middot; Patch <?php echo $antiXss->xss_clean(get_config(\"game_version\")); ?>\n                </div>\n                <h1 class=\"hero-title\"><?php echo $antiXss->xss_clean(get_config(\"page_title\")); ?></h1>\n                <p class=\"hero-sub\"><?php echo htmlspecialchars($meta['hero_sub']); ?></p>\n                <div class=\"hero-actions\">\n                    <a class=\"hero-btn hero-btn-primary\" onclick=\"$('#register').trigger('click'); scrollToContent();\">\n                        <i class=\"fa fa-bolt\"></i> Create Account\n                    </a>\n                    <a class=\"hero-btn hero-btn-ghost\" onclick=\"$('#howtoconnect').trigger('click'); scrollToContent();\">\n                        <i class=\"fa fa-plug\"></i> How to Connect\n                    </a>\n                    <a class=\"hero-btn hero-btn-ghost\" href=\"https://discord.gg/quUmkgb5sD\" target=\"_blank\" rel=\"noopener noreferrer\">\n                        <i class=\"fa fa-comments\"></i> Join Discord\n                    </a>\n                </div>\n                <div class=\"hero-realm\">\n                    <i class=\"fa fa-globe\"></i>\n                    <?php elang('realmlist'); ?>: <strong><?php echo get_config('realmlist'); ?></strong>\n                </div>\n            </div>\n        </section>\n\n        <div class=\"section-divider\"></div>\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/resources/howtoconnect.php",
    "content": "<?php\n/**\n * Emberstone Portal - How to Connect Template\n * Content switches based on selected expansion.\n */\n$selected = get_config('_selected');\n\nif ($selected === 'wotlk') { ?>\n\n<div class=\"connect-steps\" style=\"line-height: 1.8;\">\n    <h4><i class=\"fa fa-plug\"></i> How to Connect</h4>\n    <hr>\n    <p>1. <?php elang('create_account_tip1'); ?></p>\n    <p>2. Download and install the <strong>World of Warcraft 3.3.5a</strong> client (build 12340).</p>\n    <div style=\"margin: 12px 0 12px; text-align: center;\">\n        <a href=\"https://mega.nz/folder/klkUgayB#4uy6l0nKCl2Vx0yO_v42yw\" target=\"_blank\" rel=\"noopener\" class=\"btn btn-primary\" style=\"display: inline-flex; align-items: center; gap: 8px;\">\n            <i class=\"fa fa-download\"></i> Direct Download (MEGA)\n        </a>\n        <a href=\"magnet:?xt=urn:btih:322598D924EBA39CB15002928C7933E1B5C28DC6&dn=Wrath+of+the+Lich+King+3.3.5a\" class=\"btn btn-primary\" style=\"display: inline-flex; align-items: center; gap: 8px; margin-left: 8px;\">\n            <i class=\"fa fa-magnet\"></i> Torrent (Windows)\n        </a>\n        <a href=\"magnet:?xt=urn:btih:4795C2C70355992039EE7D895730DD906FF595FA&dn=Wrath%20of%20the%20Lich%20King%203.3.5a%20%28Mac%29\" class=\"btn btn-primary\" style=\"display: inline-flex; align-items: center; gap: 8px; margin-left: 8px;\">\n            <i class=\"fa fa-magnet\"></i> Torrent (Mac)\n        </a>\n    </div>\n    <p>MEGA limits free downloads to ~5 GB/day. The client is ~6.3 GB so you may need to resume across two days. The torrent links have no limits but require a torrent client such as <a href=\"https://www.qbittorrent.org/\" target=\"_blank\" rel=\"noopener\">qBittorrent</a>.</p>\n    <p>3. <?php elang('create_account_tip3'); ?></p>\n    <p>4. <?php elang('create_account_tip4'); ?></p>\n    <pre class=\"realmlist-block\">set realmlist <?php echo get_config('realmlist') . \"\\n\"; ?>set realmname <?php echo $antiXss->xss_clean(get_config('page_title')); ?></pre>\n    <p>5. Launch <code>Wow.exe</code> directly. Do not use the Launcher or it will try to update the client. Log in with your username, not your email.</p>\n</div>\n\n<?php } else { ?>\n\n<div class=\"connect-steps\" style=\"line-height: 1.8;\">\n    <h4><i class=\"fa fa-plug\"></i> How to Connect</h4>\n    <hr>\n    <p>1. <?php elang('create_account_tip1'); ?></p>\n    <p>2. <?php elang('create_account_tip2'); ?></p>\n    <div style=\"margin: 12px 0 20px; text-align: center;\">\n        <a href=\"https://drive.google.com/open?id=1BVYyC49HXTUsv0E5gp7gSoDpmtsKqdIM\" target=\"_blank\" class=\"btn btn-primary\" style=\"display: inline-flex; align-items: center; gap: 8px;\">\n            <i class=\"fa fa-download\"></i> Download Client\n        </a>\n    </div>\n    <p>3. <?php elang('create_account_tip3'); ?></p>\n    <p>4. <?php elang('create_account_tip4'); ?></p>\n    <pre class=\"realmlist-block\">set realmlist <?php echo get_config('realmlist') . \"\\n\"; ?>set realmname <?php echo $antiXss->xss_clean(get_config('page_title')); ?></pre>\n    <p>5. Launch <code>WoW.exe</code> directly. Do not use the Launcher or it will try to update the client. Log in with your username, not your email.</p>\n</div>\n\n<?php } ?>\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/resources/main.php",
    "content": "<?php\n/**\n * Emberstone Portal - Main Template\n * Based on kaelthas main.php with hidden expansion field in all forms.\n */\n$_exp_val = htmlspecialchars(get_config('_selected'));\n\n// ── Unified registration: mirror account to all other expansions ────────────\nif (!empty($success_msg) && isset($_POST['submit']) && $_POST['submit'] === 'register'\n    && !empty($_POST['username']) && !empty($_POST['password']) && !empty($_POST['email'])) {\n    $all_exp = get_config('_expansions');\n    $current = get_config('_selected');\n    foreach ($all_exp as $key => $exp_cfg) {\n        if ($key === $current) continue;\n        portal_create_mirror_account($exp_cfg, $_POST['username'], $_POST['password'], $_POST['email']);\n    }\n}\n\nrequire_once 'header.php';\n// Real-player wrappers for server-status + top-players. Filters out\n// AI Playerbot (\"rndbot*\") accounts that the upstream queries include\n// by default. See bot_filter.php for the query details.\nrequire_once 'bot_filter.php'; ?>\n<div class=\"row\">\n    <div class=\"main-box\">\n        <div class=\"col-md-8\" style=\"margin-top: 20px;\">\n            <div>\n                <ul class=\"nav nav-tabs\" style=\"display: none;\">\n                    <li><a data-toggle=\"tab\" href=\"#pills-register\" id=\"register\"><?php elang('register'); ?></a></li>\n                    <li><a data-toggle=\"tab\" href=\"#pills-howtoconnect\" id=\"howtoconnect\"><?php elang('how_to_connect'); ?></a></li>\n                    <?php if (!get_config('disable_online_players')) { ?>\n                        <li><a data-toggle=\"tab\" href=\"#pills-serverstatus\" id=\"serverstatus\"><?php elang('server_status'); ?></a></li>\n                    <?php }\n                    if (!get_config('disable_top_players')) { ?>\n                        <li><a data-toggle=\"tab\" href=\"#pills-topplayers\" id=\"topplayers\"><?php elang('top_players'); ?></a></li>\n                    <?php } ?>\n                </ul>\n                <div class=\"tab-content\" id=\"nav-tabContent\">\n\n                    <!-- === HOME TAB === -->\n                    <div class=\"tab-pane fade in <?php echo((empty($error_error) && empty($success_msg)) ? 'active' : ''); ?>\"\n                         id=\"pills-main\">\n                        <?php require_once base_path . 'template/' . $antiXss->xss_clean(get_config(\"template\")) . '/tpl/posts.php'; ?>\n                    </div>\n\n                    <!-- === REGISTER TAB === -->\n                    <div class=\"tab-pane fade in <?php echo(!(empty($error_error) && empty($success_msg)) ? 'active' : ''); ?>\"\n                         id=\"pills-register\">\n                        <div class=\"row\">\n                            <div class=\"col-md-6\">\n                                <div class=\"box1\" style=\"margin-top: 10px;\">\n                                    <h4><i class=\"fa fa-user-plus\"></i> <?php elang('register'); ?></h4>\n                                    <hr>\n                                    <form action=\"\" method=\"post\">\n                                        <input type=\"hidden\" name=\"expansion\" value=\"<?php echo $_exp_val; ?>\">\n                                        <?php error_msg();\n                                        success_msg(); ?>\n                                        <div class=\"input-group\">\n                                            <span class=\"input-group\"><?php elang('email'); ?></span>\n                                            <input type=\"email\" class=\"form-control\" placeholder=\"<?php elang('email'); ?>\" name=\"email\">\n                                        </div>\n                                        <?php if (!get_config('battlenet_support')) { ?>\n                                            <div class=\"input-group\">\n                                                <span class=\"input-group\"><?php elang('username'); ?></span>\n                                                <input type=\"text\" class=\"form-control\" placeholder=\"<?php elang('username'); ?>\"\n                                                       name=\"username\">\n                                            </div>\n                                        <?php } ?>\n                                        <div class=\"input-group\">\n                                            <span class=\"input-group\"><?php elang('password'); ?></span>\n                                            <input type=\"password\" class=\"form-control\" placeholder=\"<?php elang('password'); ?>\"\n                                                   name=\"password\">\n                                        </div>\n                                        <div class=\"input-group\">\n                                            <span class=\"input-group\"><?php elang('retype_password'); ?></span>\n                                            <input type=\"password\" class=\"form-control\" placeholder=\"<?php elang('retype_password'); ?>\"\n                                                   name=\"repassword\">\n                                        </div>\n                                        <?php echo GetCaptchaHTML();?>\n                                        <input name=\"submit\" type=\"hidden\" value=\"register\">\n                                        <div class=\"text-center\" style=\"margin-top: 16px;\">\n                                            <input type=\"submit\" class=\"btn btn-success\" value=\"<?php elang('register'); ?>\">\n                                        </div>\n                                    </form>\n                                </div>\n                            </div>\n                            <div class=\"col-md-6\">\n                                <div class=\"box1 content_box1\" style=\"margin-top: 10px;\">\n                                    <?php require_once base_path . 'template/' . $antiXss->xss_clean(get_config(\"template\")) . '/tpl/rules.php'; ?>\n                                    <hr>\n                                    <div class=\"text-center\">\n                                        <?php if (empty(get_config('disable_changepassword'))) { ?>\n                                            <button type=\"button\" class=\"btn btn-primary\" data-toggle=\"modal\"\n                                                    data-target=\"#changepassword-modal\">\n                                                <i class=\"fa fa-key\"></i> <?php elang('change_password'); ?>\n                                            </button>\n                                        <?php } ?>\n                                        <button type=\"button\" class=\"btn btn-primary\" data-toggle=\"modal\"\n                                                data-target=\"#restorepassword-modal\">\n                                            <i class=\"fa fa-refresh\"></i> <?php elang('restore_password'); ?>\n                                        </button>\n                                    </div>\n                                    <?php if (get_config('2fa_support')) { ?>\n                                        <div class=\"text-center\" style=\"margin-top: 8px;\">\n                                            <button type=\"button\" class=\"btn btn-default\" data-toggle=\"modal\"\n                                                    data-target=\"#e2fa-modal\">\n                                                <i class=\"fa fa-lock\"></i> <?php elang('two_factor_authentication'); ?>\n                                            </button>\n                                        </div>\n                                        <div class=\"modal\" id=\"e2fa-modal\">\n                                            <div class=\"modal-dialog\">\n                                                <div class=\"modal-content\">\n                                                    <div class=\"modal-header\">\n                                                        <h4 class=\"modal-title\"><?php elang('two_factor_authentication'); ?></h4>\n                                                        <button type=\"button\" class=\"close\" data-dismiss=\"modal\">&times;</button>\n                                                    </div>\n                                                    <div class=\"modal-body\">\n                                                        <form action=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/index.php#register\"\n                                                              method=\"post\">\n                                                            <input type=\"hidden\" name=\"expansion\" value=\"<?php echo $_exp_val; ?>\">\n                                                            <div>\n                                                                <ul>\n                                                                    <li><?php elang('two_factor_authentication_tip1'); ?> <a href=\"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2\" target=\"_blank\">Google Store</a> - <a href=\"https://apps.apple.com/app/google-authenticator/id388497605\" target=\"_blank\">Apple Store</a></li>\n                                                                </ul>\n                                                            </div>\n                                                            <div class=\"input-group\">\n                                                                <span class=\"input-group\"><?php elang('email'); ?></span>\n                                                                <input type=\"email\" class=\"form-control\" placeholder=\"<?php elang('email'); ?>\"\n                                                                       name=\"email\">\n                                                            </div>\n                                                            <?php if (empty(get_config('battlenet_support'))) { ?>\n                                                                <div class=\"input-group\">\n                                                                    <span class=\"input-group\"><?php elang('username'); ?></span>\n                                                                    <input type=\"text\" class=\"form-control\" placeholder=\"<?php elang('username'); ?>\"\n                                                                           name=\"username\">\n                                                                </div>\n                                                            <?php } echo GetCaptchaHTML();?>\n                                                            <input name=\"submit\" type=\"hidden\" value=\"etfa\">\n                                                            <div class=\"text-center\" style=\"margin-top: 12px;\">\n                                                                <input type=\"submit\" class=\"btn btn-primary\"\n                                                                       value=\"<?php elang('two_factor_authentication_enable'); ?>\">\n                                                            </div>\n                                                        </form>\n                                                    </div>\n                                                    <div class=\"modal-footer\">\n                                                        <button type=\"button\" class=\"btn btn-danger\" data-dismiss=\"modal\">\n                                                            <?php elang('close'); ?>\n                                                        </button>\n                                                    </div>\n                                                </div>\n                                            </div>\n                                        </div>\n                                    <?php } if (get_config('vote_system')) { ?>\n                                        <div class=\"text-center\" style=\"margin-top: 8px;\">\n                                            <button type=\"button\" class=\"btn btn-default\" data-toggle=\"modal\"\n                                                    data-target=\"#vote-modal\">\n                                                <i class=\"fa fa-thumbs-up\"></i> <?php elang('vote_for_us'); ?>\n                                            </button>\n                                        </div>\n                                        <div class=\"modal\" id=\"vote-modal\">\n                                            <div class=\"modal-dialog\">\n                                                <div class=\"modal-content\">\n                                                    <div class=\"modal-header\">\n                                                        <h4 class=\"modal-title\"><?php elang('vote'); ?></h4>\n                                                        <button type=\"button\" class=\"close\" data-dismiss=\"modal\">&times;</button>\n                                                    </div>\n                                                    <div class=\"modal-body\">\n                                                        <form action=\"<?php echo $antiXss->xss_clean(get_config(\"baseurl\")); ?>/index.php#register\"\n                                                              method=\"post\" target=\"_blank\">\n                                                            <input type=\"hidden\" name=\"expansion\" value=\"<?php echo $_exp_val; ?>\">\n                                                            <?php if (get_config('battlenet_support')) { ?>\n                                                                <div class=\"input-group\">\n                                                                    <span class=\"input-group\"><?php elang('email'); ?></span>\n                                                                    <input type=\"email\" class=\"form-control\"\n                                                                           placeholder=\"<?php elang('email'); ?>\"\n                                                                           name=\"account\">\n                                                                </div>\n                                                            <?php } else { ?>\n                                                                <div class=\"input-group\">\n                                                                    <span class=\"input-group\"><?php elang('username'); ?></span>\n                                                                    <input type=\"text\" class=\"form-control\"\n                                                                           placeholder=\"<?php elang('username'); ?>\"\n                                                                           name=\"account\">\n                                                                </div>\n                                                            <?php } ?>\n                                                            <div class=\"text-center\" style=\"margin-top: 12px;\">\n                                                                <?php\n                                                                $vote_sites = get_config('vote_sites');\n                                                                if (!empty($vote_sites)) {\n                                                                    foreach ($vote_sites as $siteID => $vote_site) {\n                                                                        $tmp_id = $siteID + 1;\n                                                                        echo '<button type=\"submit\" name=\"siteid\" value=\"' . $tmp_id . '\" style=\"border:none; background-color: transparent;\"><img src=\"' . $vote_site['image'] . '\"></button>';\n                                                                    }\n                                                                }\n                                                                ?>\n                                                            </div>\n                                                        </form>\n                                                    </div>\n                                                    <div class=\"modal-footer\">\n                                                        <button type=\"button\" class=\"btn btn-danger\" data-dismiss=\"modal\">\n                                                            <?php elang('close'); ?>\n                                                        </button>\n                                                    </div>\n                                                </div>\n                                            </div>\n                                        </div>\n                                    <?php } ?>\n\n                                    <!-- Restore Password Modal -->\n                                    <div class=\"modal\" id=\"restorepassword-modal\">\n                                        <div class=\"modal-dialog\">\n                                            <div class=\"modal-content\">\n                                                <div class=\"modal-header\">\n                                                    <h4 class=\"modal-title\"><?php elang('restore_password'); ?></h4>\n                                                    <button type=\"button\" class=\"close\" data-dismiss=\"modal\">&times;</button>\n                                                </div>\n                                                <div class=\"modal-body\">\n                                                    <form action=\"\" method=\"post\">\n                                                        <input type=\"hidden\" name=\"expansion\" value=\"<?php echo $_exp_val; ?>\">\n                                                        <?php if (get_config('battlenet_support')) { ?>\n                                                            <div class=\"input-group\">\n                                                                <span class=\"input-group\"><?php elang('email'); ?></span>\n                                                                <input type=\"email\" class=\"form-control\"\n                                                                       placeholder=\"<?php elang('email'); ?>\"\n                                                                       name=\"email\">\n                                                            </div>\n                                                        <?php } else { ?>\n                                                            <div class=\"input-group\">\n                                                                <span class=\"input-group\"><?php elang('username'); ?></span>\n                                                                <input type=\"text\" class=\"form-control\"\n                                                                       placeholder=\"<?php elang('username'); ?>\"\n                                                                       name=\"username\">\n                                                            </div>\n                                                        <?php }\n                                                        echo GetCaptchaHTML();?>\n                                                        <input name=\"submit\" type=\"hidden\" value=\"restorepassword\">\n                                                        <div class=\"text-center\" style=\"margin-top: 12px;\">\n                                                            <input type=\"submit\" class=\"btn btn-primary\"\n                                                                   value=\"<?php elang('restore_password'); ?>\">\n                                                        </div>\n                                                    </form>\n                                                </div>\n                                                <div class=\"modal-footer\">\n                                                    <button type=\"button\" class=\"btn btn-danger\" data-dismiss=\"modal\">\n                                                        <?php elang('close'); ?>\n                                                    </button>\n                                                </div>\n                                            </div>\n                                        </div>\n                                    </div>\n\n                                    <!-- Change Password Modal -->\n                                    <div class=\"modal\" id=\"changepassword-modal\">\n                                        <div class=\"modal-dialog\">\n                                            <div class=\"modal-content\">\n                                                <div class=\"modal-header\">\n                                                    <h4 class=\"modal-title\"><?php elang('change_password'); ?></h4>\n                                                    <button type=\"button\" class=\"close\" data-dismiss=\"modal\">&times;</button>\n                                                </div>\n                                                <div class=\"modal-body\">\n                                                    <form action=\"\" method=\"post\">\n                                                        <input type=\"hidden\" name=\"expansion\" value=\"<?php echo $_exp_val; ?>\">\n                                                        <?php if (get_config('battlenet_support')) { ?>\n                                                            <div class=\"input-group\">\n                                                                <span class=\"input-group\"><?php elang('email'); ?></span>\n                                                                <input type=\"email\" class=\"form-control\"\n                                                                       placeholder=\"<?php elang('email'); ?>\"\n                                                                       name=\"email\">\n                                                            </div>\n                                                        <?php } else { ?>\n                                                            <div class=\"input-group\">\n                                                                <span class=\"input-group\"><?php elang('username'); ?></span>\n                                                                <input type=\"text\" class=\"form-control\"\n                                                                       placeholder=\"<?php elang('username'); ?>\"\n                                                                       name=\"username\">\n                                                            </div>\n                                                        <?php } ?>\n                                                        <div class=\"input-group\">\n                                                            <span class=\"input-group\"><?php elang('old_password'); ?></span>\n                                                            <input type=\"password\" class=\"form-control\"\n                                                                   placeholder=\"<?php elang('old_password'); ?>\"\n                                                                   name=\"old_password\">\n                                                        </div>\n                                                        <div class=\"input-group\">\n                                                            <span class=\"input-group\"><?php elang('password'); ?></span>\n                                                            <input type=\"password\" class=\"form-control\"\n                                                                   placeholder=\"<?php elang('password'); ?>\"\n                                                                   name=\"password\">\n                                                        </div>\n                                                        <div class=\"input-group\">\n                                                            <span class=\"input-group\"><?php elang('retype_password'); ?></span>\n                                                            <input type=\"password\" class=\"form-control\"\n                                                                   placeholder=\"<?php elang('retype_password'); ?>\"\n                                                                   name=\"repassword\">\n                                                        </div>\n                                                        <?php echo GetCaptchaHTML();?>\n                                                        <input name=\"submit\" type=\"hidden\" value=\"changepass\">\n                                                        <div class=\"text-center\" style=\"margin-top: 12px;\">\n                                                            <input type=\"submit\" class=\"btn btn-primary\"\n                                                                   value=\"<?php elang('change_password'); ?>\">\n                                                        </div>\n                                                    </form>\n                                                </div>\n                                                <div class=\"modal-footer\">\n                                                    <button type=\"button\" class=\"btn btn-danger\" data-dismiss=\"modal\">\n                                                        <?php elang('close'); ?>\n                                                    </button>\n                                                </div>\n                                            </div>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n\n                    <!-- === HOW TO CONNECT TAB === -->\n                    <div class=\"tab-pane fade in\" id=\"pills-howtoconnect\">\n                        <div class=\"row\">\n                            <div class=\"col-md-12\">\n                                <div class=\"box1\" style=\"margin-top: 10px;\">\n                                    <?php require_once base_path . 'template/' . $antiXss->xss_clean(get_config(\"template\")) . '/tpl/howtoconnect.php'; ?>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n\n                    <!-- === SERVER STATUS TAB === -->\n                    <?php if (!get_config('disable_online_players')) { ?>\n                        <div class=\"tab-pane fade in\" id=\"pills-serverstatus\">\n                            <div class=\"box1\" style=\"margin-top: 10px;\">\n                                <h4><i class=\"fa fa-server\"></i> <?php elang('server_status'); ?></h4>\n                                <hr>\n                                <?php\n                                foreach (get_config('realmlists') as $onerealm_key => $onerealm) {\n                                    $recent        = portal_recent_activity($onerealm);\n                                    $recent_count  = is_array($recent) ? count($recent) : 0;\n                                    $online_count  = portal_online_count($onerealm);\n                                    $highest       = portal_highest_level_char($onerealm);\n\n                                    echo \"<p><span style='color: var(--gold);font-weight: bold;font-family: var(--font-heading);'>\" . $antiXss->xss_clean($onerealm['realmname']) . \"</span>\";\n                                    if (!empty($highest)) {\n                                        echo \" <span style='font-size: 12px;color:var(--text-dim);'>&middot; Highest: <span style='color:var(--gold-bright);'>\" . $antiXss->xss_clean($highest['name']) . \"</span> (lvl \" . $antiXss->xss_clean($highest['level']) . \")</span>\";\n                                    }\n                                    echo \" <span style='font-size: 12px;color:var(--text-dim);'>&middot; {$online_count} online now &middot; {$recent_count} active in last 30d</span></p><hr>\";\n\n                                    if (!is_array($recent)) {\n                                        echo \"<span style='color: var(--text-dim);'>\" . lang('online_players_msg2') . \"</span>\";\n                                    } else {\n                                        echo '<table class=\"table\"><thead><tr><th scope=\"col\">Last seen</th><th scope=\"col\">' . lang('name') . '</th><th scope=\"col\">' . lang('race') . '</th> <th scope=\"col\">' . lang('class') . '</th><th scope=\"col\">' . lang('level') . '</th></tr></thead><tbody>';\n                                        foreach ($recent as $one_char) {\n                                            $last_seen = portal_format_last_seen($one_char);\n                                            $badge_color = !empty($one_char['online']) ? 'var(--gold-bright)' : 'var(--text-dim)';\n                                            echo '<tr><td style=\"color:' . $badge_color . ';font-size:12px;\">' . $antiXss->xss_clean($last_seen) . '</td><th scope=\"row\">' . $antiXss->xss_clean($one_char['name']) . '</th><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/race/' . $antiXss->xss_clean($one_char[\"race\"]) . '-' . $antiXss->xss_clean($one_char[\"gender\"]) . '.gif\\'></td><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/class/' . $antiXss->xss_clean($one_char[\"class\"]) . '.gif\\'></td><td>' . $antiXss->xss_clean($one_char['level']) . '</td></tr>';\n                                        }\n                                        echo '</table>';\n                                    }\n                                    echo \"<hr>\";\n                                }\n                                ?>\n                            </div>\n                        </div>\n                    <?php }\n\n                    // === TOP PLAYERS TAB ===\n                    if (!get_config('disable_top_players')) { ?>\n                        <div class=\"tab-pane fade in\" id=\"pills-topplayers\">\n                            <div class=\"box1\" style=\"margin-top: 10px;\">\n                                <h4><i class=\"fa fa-trophy\"></i> <?php elang('top_players'); ?></h4>\n                                <hr>\n                                <?php\n                                $i = 1;\n                                foreach (get_config('realmlists') as $onerealm_key => $onerealm) {\n                                    echo \"<h6 style='color: var(--gold);font-weight: bold;font-family: var(--font-heading);'>{$onerealm['realmname']}</h6><hr>\";\n                                    $data2show = portal_top_playtime($onerealm);\n                                    echo \"<button type=\\\"button\\\" class=\\\"btn btn-info\\\" data-toggle=\\\"modal\\\" data-target=\\\"#modal-id$i\\\"><i class=\\\"fa fa-clock-o\\\"></i> \" . lang('play_time') . \"</button><div class=\\\"modal\\\" id=\\\"modal-id$i\\\"><div class=\\\"modal-dialog modal-lg\\\"><div class=\\\"modal-content\\\">\n                                            <div class=\\\"modal-header\\\"><h4 class=\\\"modal-title\\\">\" . lang('top_players') . \" - \" . lang('play_time') . \"</h4><button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\">&times;</button></div><div class=\\\"modal-body\\\">\";\n\n                                    if (!is_array($data2show)) {\n                                        echo \"<span style='color: var(--text-dim);'>\" . lang('online_players_msg2') . \"</span>\";\n                                    } else {\n                                        echo '<table class=\"table table-striped\"><thead><tr><th scope=\"col\">' . lang('rank') . '</th><th scope=\"col\">' . lang('name') . '</th><th scope=\"col\">' . lang('race') . '</th> <th scope=\"col\">' . lang('class') . '</th><th scope=\"col\">' . lang('level') . '</th><th scope=\"col\">' . lang('play_time') . '</th></tr></thead><tbody>';\n                                        $m = 1;\n                                        foreach ($data2show as $one_char) {\n                                            if (empty($one_char['name'])) {\n                                                continue;\n                                            }\n                                            echo '<tr><td>' . $m++ . '<th scope=\"row\">' . $antiXss->xss_clean($one_char['name']) . '</th><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/race/' . $antiXss->xss_clean($one_char[\"race\"]) . '-' . $antiXss->xss_clean($one_char[\"gender\"]) . '.gif\\'></td><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/class/' . $antiXss->xss_clean($one_char[\"class\"]) . '.gif\\'></td><td>' . $antiXss->xss_clean($one_char['level']) . '</td><td>' . $antiXss->xss_clean(get_human_time_from_sec($one_char['totaltime'])) . '</td></tr>';\n                                        }\n                                        echo '</table>';\n                                    }\n                                    echo \"</div><div class=\\\"modal-footer\\\"><button type=\\\"button\\\" class=\\\"btn btn-danger\\\" data-dismiss=\\\"modal\\\">\" . lang('close') . \"</button></div></div></div></div>\";\n                                    $i++;\n\n                                    $data2show = portal_top_killers($onerealm);\n                                    echo \"<button type=\\\"button\\\" class=\\\"btn btn-info\\\" data-toggle=\\\"modal\\\" data-target=\\\"#modal-id$i\\\"><i class=\\\"fa fa-crosshairs\\\"></i> \" . lang('killers') . \"</button><div class=\\\"modal\\\" id=\\\"modal-id$i\\\"><div class=\\\"modal-dialog modal-lg\\\"><div class=\\\"modal-content\\\">\n                                            <div class=\\\"modal-header\\\"><h4 class=\\\"modal-title\\\">\" . lang('top_players') . \" - \" . lang('killers') . \"</h4><button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\">&times;</button></div><div class=\\\"modal-body\\\">\";\n                                    if (!is_array($data2show)) {\n                                        echo \"<span style='color: var(--text-dim);'>\" . lang('online_players_msg2') . \"</span>\";\n                                    } else {\n                                        echo '<table class=\"table table-striped\"><thead><tr><th scope=\"col\">' . lang('rank') . '</th><th scope=\"col\">' . lang('name') . '</th><th scope=\"col\">' . lang('race') . '</th> <th scope=\"col\">' . lang('class') . '</th><th scope=\"col\">' . lang('level') . '</th><th scope=\"col\">' . lang('kills') . '</th></tr></thead><tbody>';\n                                        $m = 1;\n                                        foreach ($data2show as $one_char) {\n                                            if (empty($one_char['name'])) {\n                                                continue;\n                                            }\n                                            echo '<tr><td>' . $m++ . '<th scope=\"row\">' . $antiXss->xss_clean($one_char['name']) . '</th><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/race/' . $antiXss->xss_clean($one_char[\"race\"]) . '-' . $antiXss->xss_clean($one_char[\"gender\"]) . '.gif\\'></td><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/class/' . $antiXss->xss_clean($one_char[\"class\"]) . '.gif\\'></td><td>' . $antiXss->xss_clean($one_char['level']) . '</td><td>' . $antiXss->xss_clean($one_char['totalKills']) . '</td></tr>';\n                                        }\n                                        echo '</table>';\n                                    }\n                                    echo \"</div><div class=\\\"modal-footer\\\"><button type=\\\"button\\\" class=\\\"btn btn-danger\\\" data-dismiss=\\\"modal\\\">\" . lang('close') . \"</button></div></div></div></div>\";\n                                    $i++;\n\n                                    $data2show = portal_top_honorpoints($onerealm);\n                                    echo \"<button type=\\\"button\\\" class=\\\"btn btn-info\\\" data-toggle=\\\"modal\\\" data-target=\\\"#modal-id$i\\\"><i class=\\\"fa fa-star\\\"></i> \" . lang('honor_points') . \"</button><div class=\\\"modal\\\" id=\\\"modal-id$i\\\"><div class=\\\"modal-dialog modal-lg\\\"><div class=\\\"modal-content\\\">\n                                            <div class=\\\"modal-header\\\"><h4 class=\\\"modal-title\\\">\" . lang('top_players') . \" - \" . lang('honor_points') . \"</h4><button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\">&times;</button></div><div class=\\\"modal-body\\\">\";\n                                    if (!is_array($data2show)) {\n                                        echo \"<span style='color: var(--text-dim);'>\" . lang('online_players_msg2') . \"</span>\";\n                                    } else {\n                                        echo '<table class=\"table table-striped\"><thead><tr><th scope=\"col\">' . lang('rank') . '</th><th scope=\"col\">' . lang('name') . '</th><th scope=\"col\">' . lang('race') . '</th> <th scope=\"col\">' . lang('class') . '</th><th scope=\"col\">' . lang('rank') . '</th>';\n\n                                        if (get_config('expansion') >= 6) {\n                                            echo '<th scope=\"col\">' . lang('honor_level') . '</th>';\n                                        }\n\n                                        echo '<th scope=\"col\">' . lang('honor_points') . '</th></tr></thead><tbody>';\n                                        $m = 1;\n                                        foreach ($data2show as $one_char) {\n                                            if (empty($one_char['name'])) {\n                                                continue;\n                                            }\n                                            echo '<tr><td>' . $m++ . '<th scope=\"row\">' . $antiXss->xss_clean($one_char['name']) . '</th><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/race/' . $antiXss->xss_clean($one_char[\"race\"]) . '-' . $antiXss->xss_clean($one_char[\"gender\"]) . '.gif\\'></td><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/class/' . $antiXss->xss_clean($one_char[\"class\"]) . '.gif\\'></td><td>' . $antiXss->xss_clean($one_char['level']) . '</td>';\n\n                                            if (get_config('expansion') >= 6) {\n                                                echo '<td>' . $antiXss->xss_clean($one_char['honorLevel']) . '</td>';\n                                                echo '<td>' . $antiXss->xss_clean($one_char['honor']) . '</td>';\n                                            } else {\n                                                echo '<td>' . $antiXss->xss_clean($one_char['totalHonorPoints']) . '</td>';\n                                            }\n\n                                            echo '</tr>';\n                                        }\n                                        echo '</table>';\n                                    }\n                                    echo \"</div><div class=\\\"modal-footer\\\"><button type=\\\"button\\\" class=\\\"btn btn-danger\\\" data-dismiss=\\\"modal\\\">\" . lang('close') . \"</button></div></div></div></div>\";\n                                    $i++;\n\n                                    $data2show = portal_top_arenapoints($onerealm);\n                                    echo \"<button type=\\\"button\\\" class=\\\"btn btn-info\\\" data-toggle=\\\"modal\\\" data-target=\\\"#modal-id$i\\\"><i class=\\\"fa fa-shield\\\"></i> \" . lang('arena_points') . \"</button><div class=\\\"modal\\\" id=\\\"modal-id$i\\\"><div class=\\\"modal-dialog modal-lg\\\"><div class=\\\"modal-content\\\">\n                                            <div class=\\\"modal-header\\\"><h4 class=\\\"modal-title\\\">\" . lang('top_players') . \" - \" . lang('arena_points') . \"</h4><button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\">&times;</button></div><div class=\\\"modal-body\\\">\";\n                                    if (!is_array($data2show)) {\n                                        echo \"<span style='color: var(--text-dim);'>\" . lang('online_players_msg2') . \"</span>\";\n                                    } else {\n                                        echo '<table class=\"table table-striped\"><thead><tr><th scope=\"col\">' . lang('rank') . '</th><th scope=\"col\">' . lang('name') . '</th><th scope=\"col\">' . lang('race') . '</th> <th scope=\"col\">' . lang('class') . '</th><th scope=\"col\">' . lang('level') . '</th><th scope=\"col\">' . lang('arena_points') . '</th></tr></thead><tbody>';\n                                        $m = 1;\n                                        foreach ($data2show as $one_char) {\n                                            if (empty($one_char['name'])) {\n                                                continue;\n                                            }\n                                            echo '<tr><td>' . $m++ . '<th scope=\"row\">' . $antiXss->xss_clean($one_char['name']) . '</th><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/race/' . $antiXss->xss_clean($one_char[\"race\"]) . '-' . $antiXss->xss_clean($one_char[\"gender\"]) . '.gif\\'></td><td><img src=\\'' . get_config(\"baseurl\") . '/template/' . $antiXss->xss_clean(get_config(\"template\")) . '/images/class/' . $antiXss->xss_clean($one_char[\"class\"]) . '.gif\\'></td><td>' . $antiXss->xss_clean($one_char['level']) . '</td><td>' . $antiXss->xss_clean($one_char['arenaPoints']) . '</td></tr>';\n                                        }\n                                        echo '</table>';\n                                    }\n                                    echo \"</div><div class=\\\"modal-footer\\\"><button type=\\\"button\\\" class=\\\"btn btn-danger\\\" data-dismiss=\\\"modal\\\">\" . lang('close') . \"</button></div></div></div></div>\";\n                                    $i++;\n\n                                    $data2show = portal_top_arenateams($onerealm);\n                                    echo \"<button type=\\\"button\\\" class=\\\"btn btn-info\\\" data-toggle=\\\"modal\\\" data-target=\\\"#modal-id$i\\\"><i class=\\\"fa fa-users\\\"></i> \" . lang('arena_teams') . \"</button><div class=\\\"modal\\\" id=\\\"modal-id$i\\\"><div class=\\\"modal-dialog modal-lg\\\"><div class=\\\"modal-content\\\">\n                                            <div class=\\\"modal-header\\\"><h4 class=\\\"modal-title\\\">\" . lang('top_players') . \" - \" . lang('arena_teams') . \"</h4><button type=\\\"button\\\" class=\\\"close\\\" data-dismiss=\\\"modal\\\">&times;</button></div><div class=\\\"modal-body\\\">\";\n                                    if (!is_array($data2show)) {\n                                        echo \"<span style='color: var(--text-dim);'>\" . lang('online_players_msg2') . \"</span>\";\n                                    } else {\n                                        echo '<table class=\"table table-striped\"><thead><tr><th scope=\"col\">' . lang('rank') . '</th><th scope=\"col\">' . lang('name') . '</th><th scope=\"col\">' . lang('rating') . '</th><th scope=\"col\">' . lang('captain_name') . '</th></tr></thead><tbody>';\n                                        $m = 1;\n                                        foreach ($data2show as $one_char) {\n                                            $character_data = status::get_character_by_guid($onerealm['realmid'], $one_char['captainGuid']);\n\n                                            if (empty($character_data['name'])) {\n                                                continue;\n                                            }\n\n                                            echo '<tr><td>' . $m++ . '<th scope=\"row\">' . $antiXss->xss_clean($one_char['name']) . '</th><td>' . $antiXss->xss_clean($one_char['rating']) . '</td><td>' . (!empty($character_data[\"name\"]) ? $antiXss->xss_clean($character_data['name']) : '-') . '</td></tr>';\n                                        }\n                                        echo '</table>';\n                                    }\n                                    echo \"</div><div class=\\\"modal-footer\\\"><button type=\\\"button\\\" class=\\\"btn btn-danger\\\" data-dismiss=\\\"modal\\\">\" . lang('close') . \"</button></div></div></div></div>\";\n                                    $i++;\n                                    echo \"<hr>\";\n                                }\n                                ?>\n                            </div>\n                        </div>\n                    <?php } ?>\n                </div>\n            </div>\n        </div>\n\n        <!-- === SIDEBAR === -->\n        <div class=\"col-md-4 sidebar\" style=\"margin-top: 20px;\">\n            <div class=\"box1\">\n                <h4><i class=\"fa fa-info-circle\"></i> <?php elang('server_information'); ?></h4>\n                <hr>\n                <p><i class=\"fa fa-globe\" style=\"color:var(--gold);width:20px;\"></i> <?php elang('realmlist'); ?>: <span style=\"color: var(--gold-bright);\"><?php echo get_config('realmlist'); ?></span></p>\n                <?php echo(!empty(get_config(\"game_version\")) ? '<p><i class=\"fa fa-gamepad\" style=\"color:var(--gold);width:20px;\"></i> ' . lang('game_version') . ': <span style=\"color: var(--gold-bright);\">' . get_config(\"game_version\") . '</span></p>' : ''); ?>\n                <?php echo(!empty(get_config(\"patch_location\")) ? '<p><i class=\"fa fa-download\" style=\"color:var(--gold);width:20px;\"></i> ' . lang('server_patch') . ': <a href=\"' . get_config(\"patch_location\") . '\" style=\"color: var(--gold-bright);\">' . lang('download') . '</a></p>' : ''); ?>\n            </div>\n            <?php if(!empty(get_config('supported_langs'))) { ?>\n            <div class=\"box1\">\n                <h4><i class=\"fa fa-language\"></i> <?php elang('change_lang_form_head'); ?></h4>\n                <hr>\n                <form action=\"\" method=\"post\">\n                    <input type=\"hidden\" name=\"expansion\" value=\"<?php echo $_exp_val; ?>\">\n                    <div class=\"form-group\">\n                        <select class=\"form-control\" id=\"langchange\" name=\"langchange\">\n                            <?php\n                            $supported_langs = get_config('supported_langs');\n                            foreach($supported_langs as $val => $lang) {\n                                echo '<option value=\"' . $val . '\">' . $lang . '</option>';\n                            }\n                            ?>\n                        </select>\n                    </div>\n                    <input name=\"langchangever\" type=\"hidden\" value=\"langchanger\">\n                    <button type=\"submit\" class=\"btn btn-primary\" style=\"width:100%;\">\n                        <i class=\"fa fa-check\"></i> <?php elang('change_lang_sub'); ?>\n                    </button>\n                </form>\n            </div>\n            <?php } ?>\n        </div>\n    </div>\n</div>\n<?php require_once 'footer.php'; ?>\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/app/resources/posts.php",
    "content": "<?php\n/**\n * Emberstone Portal - Posts Template\n * Content switches based on selected expansion.\n */\n$selected = get_config('_selected');\n\nif ($selected === 'wotlk') { ?>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-shield\"></i> Welcome to Emberstone</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Emberstone is a Wrath of the Lich King realm running patch 3.3.5a with enhanced rates\n        and quality-of-life features designed for fun. Whether you are a returning veteran or\n        experiencing Northrend for the first time, Emberstone offers a polished WotLK experience\n        with AI companions, solo-friendly dungeons, and a living world.\n    </p>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-bolt\"></i> Server Rates &amp; Features</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        <strong>5x XP</strong> on kills, quests, exploration, and battlegrounds.\n        <strong>5x loot</strong> for common and uncommon drops, <strong>3x</strong> for rare, <strong>2x</strong> for epic.\n        <strong>5x gold</strong>, <strong>5x reputation</strong>, and <strong>5x honor</strong> gains.\n        <strong>5x profession</strong> skill-ups for crafting and gathering.\n        All <strong>flight paths unlocked</strong> with instant travel.\n        <strong>10g starting gold</strong> (50g for Death Knights).\n        Mail delivered <strong>instantly</strong>. Max level <strong>80</strong>.\n    </p>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-users\"></i> Modules &amp; Extras</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        <strong>PlayerBots</strong> &mdash; AI-controlled players that quest, group, and PvP alongside you.\n        <strong>AutoBalance</strong> &mdash; Dungeons and raids scale to your party size, solo or with friends.\n        <strong>Transmogrification</strong> &mdash; Change the look of your gear at the Transmog NPC.\n        <strong>Auction House Bot</strong> &mdash; The AH is always stocked with items.\n        <strong>AoE Loot</strong> &mdash; Loot all nearby corpses at once.\n        <strong>Auto-Learn Spells</strong> &mdash; New abilities learned automatically on level up.\n        <strong>Solo Dungeon Finder</strong> &mdash; Queue for dungeons solo or with any group size.\n        <strong>Cross-Faction BGs</strong> &mdash; Battlegrounds pop regardless of faction balance.\n    </p>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-play-circle\"></i> Getting Started</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Create your account to begin your adventure. Once registered, download a WoW 3.3.5a client,\n        update your <code>realmlist.wtf</code> file, and log in to explore Northrend, storm Icecrown Citadel,\n        battle in Wintergrasp, and conquer Ulduar. Check the \"How to Connect\" page for setup instructions.\n    </p>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-comments\"></i> Join Our Discord</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Hop into the Emberstone Discord to chat with the community, get help, find groups, and stay\n        on top of server announcements.\n    </p>\n    <div style=\"text-align: center; margin-top: 12px;\">\n        <a href=\"https://discord.gg/quUmkgb5sD\" target=\"_blank\" rel=\"noopener noreferrer\"\n           class=\"btn btn-primary\"\n           style=\"display: inline-flex; align-items: center; gap: 8px;\">\n            <i class=\"fa fa-comments\"></i> discord.gg/quUmkgb5sD\n        </a>\n    </div>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-thumbs-up\"></i> Vote for Emberstone</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Enjoying the server? Help us grow by voting! Every vote helps new players discover Emberstone.\n    </p>\n    <div style=\"text-align: center; margin-top: 12px;\">\n        <a href=\"https://www.xtremetop100.com/in.php?site=1132378609\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Vote for Emberstone on XtremeTop100\">\n            <img src=\"https://www.xtremeTop100.com/votenew.jpg\" border=\"0\" alt=\"Vote for Emberstone on XtremeTop100\" style=\"border-radius: 4px;\">\n        </a>\n    </div>\n</div>\n\n<?php } else { ?>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-shield\"></i> Welcome to Emberstone</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Emberstone is a Classic World of Warcraft realm running the original 1.12.1 patch with faithful game\n        mechanics, class balance, and progressive content unlocks. Whether you are a returning veteran or stepping\n        into Azeroth for the first time, Emberstone offers a stable, blizzlike experience with an active community\n        and dedicated staff.\n    </p>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-bolt\"></i> Server Rates &amp; Features</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        <strong>3x XP</strong> on kills, quests, and exploration.\n        <strong>3x loot</strong> for common and uncommon drops, <strong>2x</strong> for rare, and <strong>1x</strong> (blizzlike) for epic items.\n        <strong>3x gold</strong> and <strong>3x reputation</strong> gains across the board.\n        Mail is delivered <strong>instantly</strong> with no delay.\n        Max level is <strong>60</strong> with up to <strong>10 characters</strong> per account.\n    </p>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-play-circle\"></i> Getting Started</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Create your account to begin your adventure. Once registered, update your <code>realmlist.wtf</code>\n        file and log in to explore the Eastern Kingdoms and Kalimdor, run dungeons with friends, raid Molten Core\n        and Onyxia, and fight for honor in Alterac Valley. Check the \"How to Connect\" page for setup instructions.\n    </p>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-comments\"></i> Join Our Discord</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Hop into the Emberstone Discord to chat with the community, get help, find groups, and stay\n        on top of server announcements.\n    </p>\n    <div style=\"text-align: center; margin-top: 12px;\">\n        <a href=\"https://discord.gg/quUmkgb5sD\" target=\"_blank\" rel=\"noopener noreferrer\"\n           class=\"btn btn-primary\"\n           style=\"display: inline-flex; align-items: center; gap: 8px;\">\n            <i class=\"fa fa-comments\"></i> discord.gg/quUmkgb5sD\n        </a>\n    </div>\n</div>\n\n<div class=\"box1 post-card\" style=\"margin-top: 16px;\">\n    <h4><i class=\"fa fa-thumbs-up\"></i> Vote for Emberstone</h4>\n    <hr>\n    <p style=\"text-align: justify\">\n        Enjoying the server? Help us grow by voting! Every vote helps new players discover Emberstone.\n    </p>\n    <div style=\"text-align: center; margin-top: 12px;\">\n        <a href=\"https://www.xtremetop100.com/in.php?site=1132378609\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Vote for Emberstone on XtremeTop100\">\n            <img src=\"https://www.xtremeTop100.com/votenew.jpg\" border=\"0\" alt=\"Vote for Emberstone on XtremeTop100\" style=\"border-radius: 4px;\">\n        </a>\n    </div>\n</div>\n\n<?php } ?>\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/emberstone-portal/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: emberstone-portal\n  namespace: game-servers\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 10m\n  path: \"./apps/base/game-servers/emberstone-portal/app\"\n  prune: true\n  wait: true\n  sourceRef:\n    kind: ExternalArtifact\n    name: emberstone-portal\n    namespace: flux-system\n  dependsOn:\n    - name: cmangos\n      namespace: game-servers\n    - name: azerothcore\n      namespace: game-servers\n  targetNamespace: game-servers\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/enemy-territory/app/configmap.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: enemy-territory-config\n  namespace: game-servers\ndata:\n  server.cfg: |\n    // Headshot Gaming server configuration\n    // Loads the custom HS config (encrypted secret), then applies\n    // overrides that ensure correct behavior regardless of\n    // auto-saved etconfig_server.cfg values.\n\n    // Load Headshot Gaming config\n    exec hs_etpub.cfg\n\n    // MASTER SERVERS - add ET Legacy and etmaster.net masters\n    // (original only had etmaster.idsoftware.com)\n    set sv_master1 \"etmaster.idsoftware.com\"\n    set sv_master2 \"master.etlegacy.com\"\n    set sv_master3 \"master0.etmaster.net\"\n\n    // SECURITY - ET Legacy specific overrides\n    set g_guidCheck \"0\"\n    set sv_wh_active \"1\"\n    set sv_wh_bbox_horz \"60\"\n    set sv_wh_bbox_vert \"100\"\n\n    // OVERRIDES - values that differ from the original hs_etpub.cfg\n    set sv_maxclients \"32\"\n\n    // Disable built-in config preset (defaultpublic.config resets\n    // respawn times, speed, and other values AFTER hs_etpub.cfg loads)\n    set g_customConfig \"\"\n  campaigncycle.cfg: |\n    set d1 \"campaign cmpgn_northafrica ; set nextcampaign vstr d2\"\n    set d2 \"campaign cmpgn_centraleurope ; set nextcampaign vstr d1\"\n\n    // server doesn't recognise the campaign command when the gamecode isn't running yet.\n    set d_initial \"set g_gametype 4 ; map oasis ; set nextcampaign vstr d2\"\n    vstr d_initial\n  lmscycle.cfg: |\n    set d1 \"set g_gametype 5 ; map oasis ; set nextmap vstr d2\"\n    set d2 \"set g_gametype 5 ; map battery ; set nextmap vstr d3\"\n    set d3 \"set g_gametype 5 ; map goldrush ; set nextmap vstr d4\"\n    set d4 \"set g_gametype 5 ; map radar ; set nextmap vstr d5\"\n    set d5 \"set g_gametype 5 ; map railgun ; set nextmap vstr d6\"\n    set d6 \"set g_gametype 5 ; map fueldump ; set nextmap vstr d1\"\n    vstr d1\n  objectivecycle.cfg: |\n    set d1 \"set g_gametype 2 ; map oasis ; set nextmap vstr d2\"\n    set d2 \"set g_gametype 2 ; map battery ; set nextmap vstr d3\"\n    set d3 \"set g_gametype 2 ; map goldrush ; set nextmap vstr d4\"\n    set d4 \"set g_gametype 2 ; map radar ; set nextmap vstr d5\"\n    set d5 \"set g_gametype 2 ; map railgun ; set nextmap vstr d6\"\n    set d6 \"set g_gametype 2 ; map fueldump ; set nextmap vstr d1\"\n    vstr d1\n  mapvotecycle.cfg: |\n    // Each map in this map order is executed whenever there are no votes for a map,\n    // otherwise, the map that gets the most votes for is played\n    set d1 \"set g_gametype 6 ; map oasis ; set nextmap vstr d2\"\n    set d2 \"set g_gametype 6 ; map battery ; set nextmap vstr d3\"\n    set d3 \"set g_gametype 6 ; map goldrush ; set nextmap vstr d4\"\n    set d4 \"set g_gametype 6 ; map radar ; set nextmap vstr d5\"\n    set d5 \"set g_gametype 6 ; map railgun ; set nextmap vstr d6\"\n    set d6 \"set g_gametype 6 ; map fueldump ; set nextmap vstr d1\"\n    vstr d1\n  mapvoteplayerscount.cfg: |\n    // Map Vote Player Count\n    // config file used for listing maps depending of players number in map vote mod\n    // if the config file doesn't exist, all the map are listed\n    // if the map doesn't exist in the config file, the map will appear in the map vote list\n    // if the minimum / maximum values is < 0, one or both condition is not take into account\n    // there is no limit for minimum / maximum values\n    //\n    //      map             min max\n            \"oasis\"     -1  -1\n            \"battery\"   -1  -1\n            \"goldrush\"  -1  -1\n            \"radar\"     -1  -1\n            \"railgun\"   -1  -1\n            \"fueldump\"  -1  -1\n  omni-bot.cfg: |\n    [Log]\n    LogInfo                        = true\n    LogWarnings                    = true\n    LogErrors                      = true\n    LogCriticalErrors              = true\n\n    [Script]\n    LiveUpdate                     = false\n\n    [ServerManager]\n    MinBots                        = -1\n    MaxBots                        = 16\n    BalanceTeams                   = 1\n    SaveConfigChanges              = 0\n    CountSpectators                = 0\n    SleepBots                      = 0\n    InitialDelayTime               = 2.1\n\n    [Versus]\n    BotTeam                        = -1\n    HumanTeam                      = -1\n    BotsPerHuman                   = 3\n\n    [CombatMovement]\n    moveskill                      = 3\n\n    [Difficulty]\n    CurrentDifficulty              = 4\n    AdjustAim                      = 1\n\n    [FireTeam]\n    enabled                        = 0\n\n    [XP]\n    Reset                          = -1\n    Max                            = 10000\n\n    [HeavyWeapons]\n    MinPlayersForMortar            = -1\n    MinPlayersForMobileMG          = -1\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/enemy-territory/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: enemy-territory\n  namespace: game-servers\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      enemy-territory:\n        containers:\n          app:\n            image:\n              repository: xunholy/enemy-territory\n              tag: sha-33fad6a\n            env:\n              FS_HOMEPATH: /config\n            args:\n              - \"+set\"\n              - dedicated\n              - \"2\"\n              - \"+set\"\n              - net_port\n              - \"27960\"\n              - \"+set\"\n              - sv_advert\n              - \"3\"\n              - \"+set\"\n              - vm_game\n              - \"0\"\n              - \"+set\"\n              - fs_basepath\n              - /etlegacy\n              - \"+set\"\n              - fs_homepath\n              - /config\n              - \"+set\"\n              - fs_game\n              - legacy\n              - \"+set\"\n              - sv_maxclients\n              - \"32\"\n              - \"+set\"\n              - sv_punkbuster\n              - \"0\"\n              - \"+exec\"\n              - server.cfg\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: false\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n    defaultPodOptions:\n      hostNetwork: true\n      dnsPolicy: ClusterFirstWithHostNet\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        supplementalGroups: [44]\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: enemy-territory\n        ports:\n          udp:\n            port: 27960\n            protocol: UDP\n    persistence:\n      server-data:\n        existingClaim: enemy-territory\n        globalMounts:\n          - path: /config\n      config:\n        type: configMap\n        name: enemy-territory-config\n        globalMounts:\n          - path: /config/legacy/server.cfg\n            subPath: server.cfg\n          - path: /config/legacy/campaigncycle.cfg\n            subPath: campaigncycle.cfg\n          - path: /config/legacy/lmscycle.cfg\n            subPath: lmscycle.cfg\n          - path: /config/legacy/objectivecycle.cfg\n            subPath: objectivecycle.cfg\n          - path: /config/legacy/mapvotecycle.cfg\n            subPath: mapvotecycle.cfg\n          - path: /config/legacy/mapvoteplayerscount.cfg\n            subPath: mapvoteplayerscount.cfg\n          - path: /etlegacy/legacy/omni-bot/et/user/omni-bot.cfg\n            subPath: omni-bot.cfg\n      secret-config:\n        type: secret\n        name: enemy-territory-server-config\n        globalMounts:\n          - path: /config/legacy/hs_etpub.cfg\n            subPath: hs_etpub.cfg\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/enemy-territory/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - configmap.yaml\n  - secret.enc.age.yaml\n  - pvc.yaml\n  - udproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/enemy-territory/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: enemy-territory\n  namespace: game-servers\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/enemy-territory/app/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: enemy-territory-server-config\n  namespace: game-servers\ntype: Opaque\nstringData:\n  hs_etpub.cfg: ENC[AES256_GCM,data:cLUD9B2X1rIVs5MpWeLf4ljv3qfzxlWMRHR6Tgs0wxAZyfbf3CgSDJWrmN8Yb9kBGYXOboS+HR71m3/Qxn23SCDfgEZyA5FqEAUZ9BOJ5Z/XlFy2Ayp6oplspq07ao68etHx6Zp4Ls1B3o4SStFB+u9vNt3CNKaXkeQgpAcFJFcGWzoAbkIWoeUJB5amJ3BOLqm/306+7Vcre3LIJwN0Egz5S0U0FZc9ObDFiGQsAMpSlyqROhCtTRfMWF7cFJpE9SqsGjVoFw0aeY2wGGM7wTW+iNqzwtGXXNi13/GTlowuXA8yJVdkUJPToo37vEBWwWWA6aBYktm+/2YCa3vebdsk/+JJtt/HMU27F8GkjLOKSHDMg909YABmXiF/rpTKaSSmoSILuK3g5POmWEkXI8kljQmBTOxGMGNRU1stcR1yvAJwUFgxptZ4Gn6MP6yEuxce51/MwHnXzacuzBDD/qW3dkb1Q3jVMfa9Zg1FrXcXv3sogqWb1h0Z1M6wMCY+G+BknMkQ5lynw7ehjLHnnCLN/9axZM37RAQmqJbpfdaGQekp5k/W1uoWNc8Xln16gzZaohfjOhEmsKrrohfknXfHAvOoQfVTKTOGRz1K3EA82hESG5NR2FEIraelhd9P+IkwYaFjFY6nnG6zJDotVpXxiXirbsRWAzVKcp610zFuws4j0C8dnAqXdlfnw2w4hoo9zv2EXkaRAfe2s4mKtcOhzaQ9iOVzympN50WiTvShaMF1oE6f0tppu8nErvB1MWEeIBFdD3SK10J8Vbau65c1XR3032nybDQw+4ffTm2fC/YV1GkbnSU0mMjjwtNcnQn8ly+u708vdNk6oFOkfLOMDFWS4NpSHlWltgrAQ3rn0bKJPM0cETIPsftH438ALHg2DJ7LhWWZIT8opt1ar+wC8z+y8J9nd6CI5/5xQ5twJe6+XA/46uvv6x5fVJuS8niEj1Ww2Fl/nhJxg5+rGcDvoHQEe3mP0MuehiC3UofJ/Ugwmt2AAk6HQHy7EFL4M27IxJGv+wQabs+Cl4VkZEbp/+7iCi4dhI8WYzosN4t0XnUSuno1HnW8nK5rWCKDvS7r20CVv28SL9Mi8R5vkXw/0quzBYLpVP9tzPV/3S+Zb5jakvWZVP452vik/XBPAua/99pZugvW7fKirdOhhrz4Ewy8xSlQfn78Mj58pHJ1ScMnQW8cwrO5c3XbZwaqa5Lu6XejHsSsP+Qv6dqjAsh5hn0cRlJnMJSaX845W0+XN21DHzsO+Z4VlTH5ytbXrgk1JpEjAypzSk9YvQgzV8p1XHO3qPrXXGokRH2XeeixGncqqctM0axJqLg5Ed/mD1XcjUlfi5pSfM+qYgVix56GIh5VLyah5MalwVs7WQc6f79R88Kjt0kCPgJKPpm5Bgp7Xhso8CzXbIwM79EuTkQBuQMkRbsRBzDnsuQNUMlyiAWB/tmY90NFKqo+hM4L0ruHiXmMJ2cjqpWrGw7UPzyWqHS/P0j5piQSebalk+3SWRCqV5lbkxgY/EweZfvylFd1KxCCgW2q0j16dfEfNHFY9xOqL8y3WH3OcM5ATnhfBr7nzPpht2YNBeZmSIsUD+A/FBjooakl4uT0Ko4MJGfeGD7wZWTMlmIEeJOmpaf947qcFQooey/atOJu46vjhsmhyiXSI29cfjZhb5bBR09eQL0K/tXFpRi6OJuKrSg8ruTGINdZhyYBH9LnD7cXBDVxcXTJAIRPU1qn4tcGiKqeYkFm5qmNeSRoMzMi+SnJzfnmee6svfLwTn190UdxYt7lnHFgAQH/sbcejzsKHl9aORZdkOUL+lr+UwUIiZjJ9ectwqT70LmymDNno32ZmrnYspOpVCJZSMaodXGNNuVyhopH9F7kN/3tGFBs12Y9Nt3FK1Jgs6VAfnXXt3uiE3WlrVExq/359GR30B+G7bDHNcc2eMZNDrnEGrk+KBKod1OjpvQnliPxXzCg9lLWm7tyTQJyhPYY5YAzs5XKRr5oQVhbufdObiQfm1FmOpJ9YlNbaDoDsZEUQ3vg0WjN7dTK36fFcO5mqjstAcvbIMIGeiZ823r/HRMvMFrVY3N/r+O/VUZXGNetfAJ3Emdu2MISiKGWXq5I/F1j8niUxfEGPNtj9JqkRoBHeb1fKHTWIf2QaWItcIxL/NZsAkTLu9STadAZ/N5j+hkwnGMOl/QTKzvTvuOYx6+Tyw2IzfHSJsE05WMXstn+XD+P3Z3TDNCtIhqhXEUZ8gMiYvu9btCenJEzmxbHrMAlQyDlJqi5g5kIG2G6DYS2ow+dr348ZOcy/ydi9dfEiv0wZ+T2JPSXq8tPW+jXQXT1YDJh1WZJDMPGC8SjjvtHmbkJWR7SZ+JVUAbfNT7GUUlYGu08pTk9t1iLmd+qjxr2qNWYIB6SNTgez3zE6YlvbwRdsM4IKeo/LrnebdL/+EKEmYDa5jx5jFkDjrUluqK96yMFLRAa8EeJMy3eJWin833K4GOnDi/Uhq8rBT2URLUTEHphkRdSZ6uKCzyEK5gjRUDdL5xkbgOeshqxzWdlLpyn0AbtBGpgp/lOheNVDFLFtn47suv7LNzmjTnxtktZL3aSZQXfNusEU/dAAG35L9ko7WJJSHh7PpLfB6GODTLEzNTui1NAzdjChsXA/qeOFw18R76LNAjwrjVVyqvlbemqUo/ndL1b2pr0TCC/dQZBXf3WTumcr9hYaA+HQPaXerb+Jkwdly7T3D6hMa1LbzyCrJy8QFL5cGoky0CxY8yh/v1rZl3Al5wt13lVjujI7+k5nXNdJ3S08vFS+YZmM8fISV2Paxd5adAPgQ6QJCy8XvvB4/pibtiKWxRy7Uw+idz3QwNwCn+P5m1z/mYeKHC40G1XK+YhV9X4QdkZmxprwIwXDzcX/HYsfnbOS/1XgXkMG8iPy4XtB+LnKCQuBD0D7u5bQMAVDs3A6LF5Up7th6IuZam6iKEUTBOLXbFQhw6b28y8AdAWd2Az47oVC0bOhqbseTyfrx6StbQZjPeJJWZX5JP8FJLW3b1e/ZFu62XK4eHD4Yaio+5QRLZlJqmScn8Eh6LsWNlgkTDWm3AZdkwSoPAKKAGKjVE1HTtVHCJXmnw5qScrF8S+y1miNdqCmQorvOU+mGHcd4b6pkhH9SQc5NYgryUiUDbZxBhoES10dTW7TrTcgHcF68+EnP5nGJv8wTho90eUbS+K7bHc3p93WlWnGit8HPXt41X7nmG8A/ak3KKm+7J2EPkmyj0H8Of8BM1Ktnl6yk9r52x6eg5V0EHJea4gdnlGfJ5S6Qa4nh5UnQ1JGxtHfzf/jLEDqUPn6fhzpSFWTYjFgpSCHlINHZSApqPIXxGRnHVJq4lEtiDRK3IWM5FkzNoZrT8b4qT5H1qOsP3pD5i6GzlY3hY5vU90OQXKqglVMTQqB9gxwch6ZxyOkilrD8JFkr6pDNb2+LCjWB23IoMn2raAF+bwKAUfTvdaFHxssxu0EaycB5s4X21ym2RRN/9NM1B+ZrIIQRNmSpnC5sc5lLGLb1YVuqtWkVEWzqd7ElMYY2R9gOIFtePa7Eb8P/YL77ffQ7wTaDYBLdV86HyZClZVLQ3x9hzdHA2dwXTkvbnOZcF7IhQ+c/ZnMh4X7/0RfA9HG6qZn8GdZqapQCUSMzWIbBzDnOR9X5FqwLhSuZqFBoxGxPNXR6B7diojuXuW1CgL+nYUHHUOHQ/yulewYxQjf0LS937q+3QN5YkZUPPtnzcrJRCwjCUW13ZUHCY2//8keHM695LWkzhw2ALqnseaq15tj0/3kOx4dMUFv9nccZzvwnRc4Yn6M2RwG9e3IZj19C/q8tOeep/yDXjD+/kgh4o1sc/eX1YrDvv/DTVTvfjXjJXl2NnoIvC8qdTSaLAxg2nZBHhKUy7UxnPD7wW9/g7Q9/jDWBcvBtgqVHWCEn9/oJs8DtFxNUCVa87QX+Pf8F4t58xCDNuSsee31vfSSYW47evbumta2lg3QVAFUfVWYB0Xd0XIXUZrhdP7ebAlAPQdt6TcgIK5rbClirWy/Dnyfhrm0tKacM/b53NYjMMIjiccATZtRPLGzuKIY2ZU+LoSAshsFHe5Cdys2ZadI6fz00FRx+Cht+l2i7RcnBU8aLyM9TDc2zJS7azpwYPFi9nONNv167dNffg00ZVY0sLIK3yuUtDBBZmtYO12BsDh6E+4Say8YcFCT7xKIlFIFPqUGHpIvHV8QW98bf02OqnWZbgdgb+McVyNcORHQW1HKwgJfzV7ueXZhzCYOgFFJsEy7g0i57FlO6AFMMqM7zjLH7hoUFbPh2mlJfQQXfwSavYKGLtQMAIbbaoHWGY8LDK2qLODdpySA4j0B+vw8OgKJdOAHoMKoYV59bX2DfLZwlWj420dGyVBZcp1ObGpiYJtPO3AJfayZXeiDHgy91qg8D5pHTWPWjNvL9DvAUb5bJZYSSm8qlyAC+eaG+RbnDzHMZbjIAPcbyJXEvuAZnzfcLmDmZTWLeTuAOQhUzZgJoSQ3c04dW77OE62pdH6URiuEWjAajvxnH4UcLtTikfZE7SxWpYxInvnqvDUEhfbVY/SNmW6b9YyoJKCw7bq+QpFwFBnrWa5sJumENmGqvMnGpYc+B0KrmkDzur0gJzW5RbqPsU1RMHKBH6O5pq3Z5O7MY+sX5emW5LG9pOYFiaCnrtvmjTW+kBOBT4JT/4ocCrapbdijcEJqSLx9hQVcovLLC+IMtizb8bosipW4+tXL2giKYILcW/PdG0J5MfGGIJ7LcTx1cgmH1UmI4A1EDFj7Vuq4oQm04NnYayGH4jJ1YE681VRaKmIf1/GCcbmRBOE7bbPUCNonQRx6hvZIpcl24b2pDwPkociNYCNHfn9zw+F3NUqu02r1RK4re3fSyQn/dOENgsltr8nj/6uv5d1HynJidUYZNb1/jOH4bXGOLqIp2Xr3Dhmpe267tvttgyBAMhYW06tmchumahSMqLCCI7Bq4b2oAwrxX+QjKD9UO2zI00sbYkhViokAHQW5V7OxYQIUMQ5+XzTxUaw06BxH3zzvfOA5WPRRj7euHurEoy4fdndr0NdHRwdNalpBn6jM8LBYAV0x5YrAVypCNE9iP45bPK4BLPolf8lGk1mGtK6BVMrp/yKKhQE3Kf6UYD+nRHJtxzyONYdvDmr2UKKg2A45rIl2gv/jaf5hVMTTLYwxnsmlQeK90Tni5Q7yoZ5/X3jUM03XTxZNnZO1tm2mnxtI3VksIX1xd9lIalYG+XYkUV6t0FxGhm2oq1e1uuTsrz5GfkbH+kqG/e8yQp91kSX49RCw7Jh5A8AnvMOSnybhvpYWVRQF5BEprG8e8Hj15A9Tkkl2AeW82OWfzA3OW43UToY4N199e/CkLtI0eLr302CMq8RR9c4AXSfN8ycWwbIer4yLPFhjenAPx65zOJChJPdr8NJ5/cdqp1WMmf9SFDP0Pk/S7DHXjAwn9M9t34wFG8rSZWTeasietNubrRdsczXqYFbkjrSkTa87Kmarbv2ycGyPEmd7mb0kuXmUETX/Zw0c12b68POmPPGYeV9G5bWy77Ila1xu78ZOGG8HfjTywEvpSogZC6zxV1lIcR58Exr7ZQ7j4ysN4fdB52p4CwcSMkT0i1/evdZlaBr0EnJ5JNX1Avhuy6HX67e2HuBitvadWP5Zyy6qkXtb/AmIc35wDjr1Ri5+8foRdBwOSUTkgoLZdpYIiTebTAjCudNDyEVqqnsQt5be0OOixpts6RZSkIUhvR6GypYecT6iVtsEq/o4eY5S0NmhOqiCl2fKTToWvY1OG04I84rRto0jIR90MvuJrHmcPocURBQeoQ8t5H6838lpNcx8zaVvatuk82xdqiEYrF/wC2CkL0vw5ACezI30D3KEFUMufdVFQsQ8AUy3Z2WqtCvB/ntPJm9rcF2IS1rMn5KEc/G+fc3MAUkKp3r10bsGFfI9qbmfZcUpOoTKd9h4P+npgVpu20LK6j6ApCimbrZYe1mXfD54dzONNcwBoiw0/yKtgWYAkpAua09o8V7le50z0XCqNgkX4sOxz2ecsGr1OpXhGryEoImB+A8zYzALlgSPUVbjyk82GuhXuCDbYpeUumOe3Ajs8XS6xtmtSF2IxopARvPXTv49Wk3yQYU6sACfJqqmOkELN/RksP64v/mHbtSr/5WtICZrzk5+aURrBqyqe/zFx5uQpeZby7cTHU4IYpziYuNmBoTqzPg71zKsm/6BO8hjqQ9JwQbiJpXIduJuc1+Ul2Q+YzX6y9s1lSDyhG0CTxj4kZi+5GHR9Dyntdkh8jVNb6kez6xa7XqEH2ijcu1DNJ2sWWtihyeOhu9oKlC6tOl2aMJc4bOnhoPHwcFjsPn0eEPTv1dc4gEB+xXFc8uJLjofvY5b9OF9px9JvcB3HoogL/aZ3Wi77M5TbKSR3/d+IbGgLPgXg7nrNvCNnZmW0sWJF26XxIoqTEA41Skk4F5czIiGPXtUMnrbYIAY6kGrRvpEac6/asYCPA1FZ24hyBtSXv0cqfzjz7H0yhxpBsN+Fh9si+Z/WAiW5NlTQdu2+pFw9rGvNHmFNUyNmjJVg5FXwJiVBx4Hfh8pdC6Srp/QGRFoU43OOFh6K6iLDlFz1RbFQ/4up32Rzti0jM6LphhWzK7XHhbriMH5Tt76h0AkQ+zYFseXJ6WspGwrqODqRSnYt4fLiEpIp3Rxm4IeYvsj9JEwhXgJtr5CmplX40T+B7Sq9IffY7ezCNQNvsQn7Yh+hVbvvg7QcLyOAT8TgGmSxL5OQ9pFmWNeImgI6Wu0S0YcXm1SMYJxn5TsMN6LKrzSpQPfMg0czZCTxdqnn7+xbzU8zomrIXNdkmh6tPRSNbmAbQEVYiUfoFzsh6oyuXnLZWtraEy2CKCcq6V9JGSKJTAIeHns5opPft2H61Sk6dKA+hHZeOkhnrr2vCGIMgk6CpJDBq9tJHfkbnw0KY00v5dWWkrG+Tb1ju9lFppwsyWXHOC0SrmcqOdALQytb0UR+8Mm24ZxVbmJdLK6nSLCOc3t5sZa0QTRmmWc7d+1gDphsTLJ5KLYQwVp6rMHpTNsWDl/Pwzw0p9kibtZSKx7U7URbXwqZqJPjTJsiuiinj8VfZkjNtJvqskCRXAbGDnRYZSbVYcWjOcNUgEHi+WgkpB9Ra4krjfghQDCEwSRnqrVQ8wcHGoA/vNyebm4AKyTp49anvuhbw+wMmUJVI7CVb6YPw0N8VCKV6jbpjE/uo7vmdSVkNu1LlAhY1hK+dhCUx2U8bDAjeKpXAqBvJu83B51kLK3n62OA4juBUJU1axF7YXk1DYYkO15gJQ+At+oCWR4dY9tBNfStffe1xwiiGFfMQQLKgJCQyscIe9k+rAqpuT87QH8zBLdnM4A+n4vbQhPKzBeylasI7YL7GMXQ22/qDR38J570J715B+lPED66z8yIEJQXzZEBh3z7EuN19cI77yC0fjPUQ1iu7+/7F239BA0zNYlFw5vW5FWLIMpK5hAnbYk75SfsW3NNaZeult6w1/YCCtV0I1iwFzbORLyGOOQDA2gDkRTFcThniD683mjFDDQkkA3LQyKKrbPFV84gT0tA2FtV1cm0HklQbR9JfDjYwBocmb09syFWX+BOvlnqF2id4L7RalBeRZ1j8k18OpKnWJb4F637xI/uc9CjNcPjMYTHuwcqLXuHyGlUnAULPwIKetIYRMnnzpNALn1cAACCghdN/M7mVOee55jRcs0GykrDqmjnKLVskCpBS9+/i3GH+5f4TxXLH+RschaVJuP7DnovWAyVtnBk3vhTxgiT1oEZ5hMNAwd4vajLh5SSWFpenzV/rcCWeAG51OZgZ49galLqLHSeR85ZkRqgkxit3uXAxIYRUl5cg9Lo6kepkrc1gOrv/DRWmDkcxqJCnqNsTUsw8MtfNMjdPG3n1KItGjjVSgGMAuXjq4WOSjXS8WxH3mQwSugNeYDpFMdEvTekmHljUXuBV/KisKq29UftzzOShJHAnCH1fVYJG1BT7JUiftICfhYRbHD00sNRqI/7wVwdgBo+HnF2eeUHtakVmp12PkrGDnMl3fCLoNO/IemSV/+SjJ0UU9QomTPWEzU0MTFyHknda/5jQ8jCfGBm2J0bdA53XwkWwMI3SEDFvu1OpMO33FX4hGATdaUfQ3W5Ubizgo1A0/T+00ss7JaDTkgG7u2luFAohWCVEG/MS4G9JvEicOFrqQn6ivwHQJ3ONmLvfDBjw7xUI/AnzM4zG3uJWhpyOIQ4Ad/hnBpW/EB98AQ+oheK4dSbH/a/XNU9rVAyxlZ4pf/ZD+a/OOtqImfUVtBUL3oFYtamgWaSUreJUU727BN7NMTj4aTB/3g66iI5ixp3sj2aCnSOoNy8yusMmKva+jd3ozxUXMjyTfQvyRHCoJke5Mrj273sDmwQzmEl5ztJqLUfaBVMII1IzrElabxCGlrAgdHTuTvl6iKp65L13ajdeH8ETRKTU1V7YX/mqZoDDiIdOcFcsbpB11qOckeEp3aKJ6AKkmvm+r18hNMcAGdlkfGhqoehA3n6T0qR5R2R6MjRrSE4Z0wp31d7lVWngXZgLlSe3g7YKHNq2XOVjm+3IERrhpiEUbgWi+CpTScEOSnMVmr/x8dbPILUP9yBCCV/c+/CS+DqnEjZXSxgdFlcxYoAmofdDoHi583OKl0RzQhPyRapA5RvqQZduiZP20JkKsqf6UZuUGW1dC6qXXFusz6zEtUCVK44ZhU8UtugevL/UuKdcdVLIfqzp0iqKnlRHgv/EVr2tX85Daol3oXnZCI6Hnp6Ij4fyVZgeiWWUBIaEKdlRv3uoy6f1zZq78s9mV+HN+/wsnUbxFN4ghqb543A6cHTolMZxHTZcA6sC3+2zY0p8dbKezRfNDfJjjQaCxMT5ZV/4uDLlkjxJcIQtE3CZcz+++tAOMoknCdUwRKtmTvqP2DMayzH2H8Ad2o1c1uUdOF/4d2g9LsEyYp3IfpG5fzvfzLBK8KqRZyaDu3BdjGYnhfdh4niJiDXgO7e7oggG2+vK9tV0jZsfTU6Jcoci8ODZPm/+oXeyb1EL9SX2DGOMaBRzPoagkZg3mDY18+t0atYhComOd92gEZjTX3NACSGRAUeJns35hYvIIeIjTN/Xl9lfTTR44VliKb2rD4aDuFbAx1v3bMd6HyDjcDhM1rJqYhjjOHGnKtkmhrAhw05WFHmTCHBSVDNoSAz5AiHsHPVXaHYLkkl/PUJjbpfwyF66uVk8x0xHuhVd8t33cshOQLbYYpCSlUYkINPSOv4p2fjblw8vCox2PmWGYML/ktzO1peqnIqb5zKAP1yXHFN/IupaxHNIx0kOIXku2elEJfSHylm6SDbU6VE5cmakFX+dgFVtrgjmzQWkeeN4mT2ng0YKw63ahYqtZjGvixeqOs0ASX56U3r78LXNA18iicBc5cR+Fxzbs3UJrF5XFEW3zhEU84znCVH9Z2+S1reH/FkWfg+rx7R5TUgIG2s43pc3JVAfhVlnX3c6W/b7ByU/3ZfMFCVMbjbeeJKX7P6tJ8ofQJJmPj4P9e3suayfsQm8m6bKysRChgnAXb0VMd6KDE/kE7ai6OVCHZGInvyds2mVdhZU+zZliqLCCCZRlRMkwH/f854OhZNnV5EyqBH7TtHuSUQBFXZmC/bVtT6qRvaxtO3Wap+v+XMZX9Zyn/oxcaLzP7XVc/5n9X3cMQha7guWWEUAOVPFBKxXHMH2LxmIuHJkWJWMb/zEeGF8UbzpfntF2hCv3pqBZt9thZsqtxt5cxkONfjBa+Fpa5zabqvMlsl1fMTWia61IyjKH2onIZh78WVwaBC+HYf1bKSC2HQCI4U44XFKb/ovjWyW9JWeLVvWrlTR1PuIblCUw72sRzkvRohKQtBqTXDqeZNoM+5aYRZ6x43s+YS7tKrNQ5UIc23vf8Kkl8YEKtlYsjuMyIkGWKV5JkOze4hHt51D0U74HWjk21D8DWADxIoNOEBynlrpwRIT8xOIG7XV2qTKoo8cfiYxvxGoJtHRsOOVdIsBsKsGENUOqiDVGr+4WhZ0kpYsaY29tcQF9/HAFBcyTdlHwGmUKoixHb56Id4tfa+hV/2Gk10lk5UesfEV/I4pZv7CxuJoTuMVHgnkiIbZGRs97HQKcLLgqymgVaZVeufcm+mbK782uq9+cqGCvYECbbE+YIeJqp7TXNvhebY68veIy1mMhFBk9vH9F3JlxO0GyfMKd5k1HQukuYUNV5qigNQ5Q/iRmwZrmQMUIxHmy1SsWSKqCDQDi/sU3UAvIZNM/cDARPgcPeXhspOCccorub7YFnq8M24o1EaO6Uo+jey6r2boQKHN0DYgOaHhJYJcqjD8lhcCpQbNIqcY/LjbA50ENutckKE4ZJkzv3UQ99gJ5C1PM4yZ0FN+nJny9uGjpHkkbvNulapfMT3b+o2JTuUtK7NTni/2qItoouqcXtP+9n+ZYW1hR1BuZhfKTX0eMnsZsHY/Dc/auKHE9jSSnVrQ2XeRahvGjrdyPFd7GihPseju1+PeZA02mn3H2k/GHExrKm8SOR48hq1hUWLel5ogdcsyZB6IkYOX7BI6ZBzyma15meh8Qa5HbD8IhYeqgFdyILBEHYJ6iUpoWlyX3+n79f8WgDSWrZxwU2uuThSzRG6HnOMEA459dnwkohZmeoeAHMWc8i7i3nCQ5hvcBvl2faoaVIrdvvqL+PRIjXcBmEBOFA2F45tZ/23wktIXo+oD6dGYQRr1ipZf8VAXg5bzynWZtfUYuE+6cwoVtb8K4etuhmUt4N3OdoZaBvKvYm9Y1wz+xYCPAksLspPhSsY9k1bmnbNqa3hylUjtzxdAlQFtQjJwywQGIPQedzWIu742Y5qs3IaxincZt2Zm44Rk9c//BBY6gnSAmTPN16iauAj2STS8YFrTNYm0k7gSJY2Ws1vLwLnDVlD29aW90GBFUz2O7Oidp+yKraAg09tSV2AbVqeI8cJjMr0QRnKjCvk51GjD+dmg+hUyI61GD/+JuakOlAa5oaA8/drUvvp3NLsp4YUKoSDPQiU0Guom+JasT0wLADkHwjNTSolBvY6JbenPA08w0AIXwhnVgqx59kv7I4l2bjSQKKYN1B2TMEzYl3IJiv38rDeTfrHx2p7so9gvyBxyCTVxOLmQyDGSslzjUtmNReLbu6aAWlyajY9GyuWBCL4QAMZc8KElmy6j95ao7AKW3y1nP+IlIvRa9mc+/G1LkiszwpUXhgTLLu3t+YCpwblhvfSi2/dokeuAlWUl9sYXwmNoxFmwgp5kfTu+sDeXkwJeu52h4JtTanfESCP2YAbTtdhmxt/Ddag3kmJZsP018+qDpO5+usyhI9ZxagtJl5Mc/6ku0vZucvAIrmEAXiZWjZUqNWwtWSqLZT7fcxJ4TgNf5D+8xCd2+b3uJSlv0nTO/AOWeQ6dBIkBkuXOy94ygNt4Go0BE+A3mU/i5WlmEooY5+ONnJXikM4FPSeF/gP0/9mTfwj65C9oI3Hs+FuyGadpWFgxULJqe8J9AtQbzPWpf0H2GmxescMwln1Rx0x7RULWHxAjBE5a7U2oN6nFfyso+HA//6SJs5Alu0H3wZwZdqo1u+GeDHWp/KKrddDQOY1SfY8JTn8fl/k9mX56i56RY17ndQOL9DLYBpu/hlLTjxHDfs3nuExTdetamanseJ2cUvdfuu3hLUZyvjE5ImhWKwz25pEQ/k+c+sPZEPc0Il5EqxVCmphWJsYftNJQQxwWjUVpChAbwJLxEfvyUyS+U3c+weTbmDzwVcygRdx1z5vqBo1552/MY0WkbQdmvIiJVIyJq7CTnozr5CKC1v57prpxdFyjdccsmb/23MChdWMD0KiVAbx2VwZ+yme6gxI36sj7WlSZH0+RvDDH5uK5xRYp0k5n+UI3d6x/rBOiQQibByuzVX+B2uy/BeUMlGa8JsU+LJ97KgVy67Zq7VdEcbwcMbhUg4x3onnr5Jpbk0d8mLXhiWu8ouTGMfiLSh8goPQynKejuSDR/uttsSkeovzYTd+dy7Lh1EM9lpQp9R4DQmN5p0ljTJj1i42+aP4jnJO3u/HD7TODo3/ZM7Pcm3sUzLPEveGCj/09Smj8qMWkARgl4h4yBDReb5qtNFPcWuIYCf3Hum6tHHeTehlPFHFqfB7HxjjRVwYAjRejumi5BXF/+xgn9K4tkmP5IFzzWQu3zwPqWdXbWw0crrQ+0JUW1iIOgYpMVtck/Q26lxJXpkQx2cV/ph0gop6RFDAfG0EsFpqoiMuMF+PmdE6eUOC9lVMLtjv6y54e8YMbWUI0Jo0BQLfLf7QBqWcwNHxy3vkWU6mSfDAh3LnLjREAmnMgAYzRT/pWUdJHWn5ndaPKC1IX0VMfZ0eb2Sm+lnDJta6YNFnZaEVTmQVV5oJArqrJ2GHNSzPLjNCQQ0m62pGCEH/8oeJXxoltGjnTHlNR8zHX4uwpsoKoAzxblHvy5s0N57h0yksF/Tl4q1mJr3L047tWW1R4B1sxAO7lEB1l+xDq//C/D46MI64i6jwYOfh1CIIAh5pTV+k9TVOuH3xcJWn2Lf+wfiO0rlTHxRr7DKd1cT0dPuvf5P48K0VkH+qPXvIAsniA2FastwvbaCuAICi0m/JWo2wewbchbARMaVYQqB+mHGU2d3VoW8svX6wmWClWoSo1WfngB3BR6/imyGf/u6cnf9YKbacl6+adOetJY5QdkmF1kQIXgeOyleI6L6710dNLCixqHtidG8aL2K7rHHLCcHczBXM8IMu+MCWXPyfUmRc0nEdmabNOI3CYwYzOydDC57XETQt63CYMEyRZTMSaxXBj9qV8vQqAjU1oCVBe2QwSZVw6/pYkmQzNdlRVtpsi5mAtRi6LGOjxe3Nh5+Hh5E76SbkaYq3b5B4/s8s47D6yyzYdIIq3h5rtca/dg9SRGE17YJoiJvUlvRoJkILDuNt6QEZ4Mvx/WmOJnTJ2fjjevGjcg8jTb6uIc/tsZfqoKqs8kubtJLkIuo49P10xSD5cghAky1quRCarm8Cg3Y2emyvAo0vZi6HGQ1q0NwIfyaxTutgoR+7bH/b17skfV3UMDFwjvZ4yYT5CDpW+YPmE4Ia4kpTBNU3GD2Vmijdu/mh/0VUYHUGbBHiE1JvjzfGxT1jnamOES2oOlXIIv+PnyomlKZspl9HhG6zG6Rk4QqtQ8JgR+xgzvxdEejYCjWmhUHFSlGurWP9ZPYdyw7AGAaLjqhjkon5yKLgIz/8SZh83aC/u2C11/CkzVRIjdfRU9tFxdk/QLxZys8Y06luaLMjKHQp6jDEPl2GYWmI1YNAlQRsGjHSQQQWZNHF9hd8Xp0H5q8OA4ZJ/ghLsoRYCbsR/O5l7GjASW6tugSnhATY1C0g0I/V98P957lW1zuRI5fbraNonq7lHkEI9MLwyFAWtyL002UIhCLcYfxiebyD0+GC8gEHETEmZzZkGP5Ii3wRhPVePkuisfHyXO8XMz/HvEGqdmbUqOMpHUdLruRUrXBKiRhYPFQRFVAkVs1jUtHRQCukK52fzGnbXJXoVBdhegpmnpKr7zv3nndKfOqKKAMGIMHhjMhJy2pcCaF51CZEn4lDPm6MEk9D/YaxBdw+nFiKm2AJyjYvceOVjDYI2rG8Jj3ft0CWAcNhP66pzpNLT487CVkpgpPnFW+NVNFBSsZ2/ah5Sf4mo0MP4+zH2LMfESB3QHwFaaplSb0EyHhBDOZR3JotZdHhUv8El05AyAv0SonxEqOaUGq5vZ/Zs5EG+px5yr9qj8oox1yoEMZ17Z5zpf6XyuWDDeaxzUqK3u5Qu500H7uwt93PJ9HuIJ+1+TdRzf85nootKISRPqZd2ozWPNl4Gbzya04F3uWC7zPAGLnqIQQJuTEw+dCfGy+Ro3So2pIpX1J0GlQTEAPmLhfR4zeyE2sOl7ZKhUOQhTEDpFSmZDXDKfS+o56e87LsCTymINUUCSw6co7ysKYmRFQtHpNGy69lXRlQOxryrFK6l1EE+YOnN7TB89gMfSiaFlUDVpWrWx4W4891xcOm1a5B3vjTlQnEJQ3lPPYYX+7nGIZP6/lpjh/AyvuU+DrQxmsGpWDF4pdvUG0mbObfazd6M1DsA1l2PsxL4LP2z3ws5mdNzcBbbQboPYsLvRSSm5HX0zn7tv6w8+CtNU8hu4fxE47d4lEcOMO6x6j6OiMOhhpggJl1ay8e6KX33MNC982XLBD+U3GFBK9YpmFj1ZOwUt/UxrN3yyYcPdEYhY7n3fosKz/mtLB67uYkjqThgQbeiiONPdGiimpqhY1Pd0Z3tu/pHSErgYXRzQNo+bUUIr+EEYfHjsRMWQ9evA2ewi5yQW+Zw52X3cRXTXG6zaGDPCP+hGPNpVXK+FcRh0DS4g9ECVP4457Fyz/xh58WAJnqiOUnfosJPmXQbTxCvl31Kxpe6/PN3236GX/dDQNq02TmzIWd0aeR57tI6WHEBG30w25rHP7iA9ENA/h/ZdAYa9x5pQGQv1RaEexk+fQNDUrG/Uu7YKvHf11Q2m0D8qowzS+g5M/4i6gD4bCUQAsEx5JZkfPJl1lTAP2CoVXCAzqZf2yLwiu7sVrto2AAvoWKBUKRcnznHxnc/dc+nfEXRVXfCGa0g2fqCY382Fv9l9tfvFJrk2qXwh98uVSeo3eLIV1fry/yvOp65dFln5QMCfPw+k+EgiWzdY7PGFHXhTmB75G4mkY8k526ur6rZLuLZzgbPMtzOHYR1cfV+ink/lUazPX801k6ogaqOcuoYYohmNnzZrJi/QMHwm+U8Xwz6SWnyDWsGf7wJGdp3/HDZhFVEWwweMcMN4ZW492RsVxedJ86MLT+wivDcLhRfoH6T23Bu7BX/ZvdsAIfRi/Xeuk95rzqDPJ/Vmq/Py2U+N84RpLm0LnH25H4z1MCY797mKFi8gzLi96CaWg1rJa25TGX590stONDqWQD0CMgwOCQpYlk/QqTlDp12mAOyke04kEV/NKls7grhf369K1XJri1S25qywuaCv5tY0J/sezwmJBoQcSYnoFbutr0cppa91jAtpphbwVkslsIPOqAWcCWCKak8Jc45G2866GD1L5gIKk9kawraDtRqy+Lq51DI7F1s/JAu7l4Ioz/WmUYRmNi8NTIZ3w/7A+VT8r64sJI7+phhz9lFk5NyTyZN1lKFKKT/EA/QhapSN/hKRFoS2c8Pd07weUdM3OWb+kkeFaVycvO10uJFwF+wWiqoIwD3W9bTuRUzxactA7rE4OiIoCrvjdz9dkw+GM4hk7hEVWl2Qps4u0UlPVPA/JODR61lSGWdCSRO0diBtFFEtnU3o7LVIh/mVuco8CaqEfatu2HEEI9OeaBLVtl0/W425pHNQrNMYUpQ1149xMk4LR6miz75xFOJH4/sN+u9eFaGqLR7y5dcx/5UT/V1pg9j34cmZHVgE5zMeRLt2AsntkKsJUdBvcajv7fW5KZdvqJivbGlKlvuipTyruLQVEFGiyHrBaYcjl5xak5wx6ur+xj2jjZTEPh5+ZQaqVcw6RzQAFYvdd/rehE3VE/Uvj0PsLfMjuojp33N2/IWxBQWcw+IAom4UWlF45Psxr3TJ/NXda68VmuzOvUFSWmDeN5hm0Qr1ayCup2M+iLWyWwGzNEpDCpktEg0Bm8wE1rp+1paBHU/YC2UKGEYaNpl4u8jr++ilxziqztZT0c6ChTabzN4feBD/xTl6Wu9S3lHyGDBuyRXww8EwCklySVlb6cjFmOJyplY9GEKYJxkRC7GTd6TpAX7jOE85Nxkzit/E7i8g5AaKo1/qV1rp7a+3k8gPX5TvontAF2tGoo248l4Hjtk+n28twweTyeDgK7NhPnxdVaKIsVY5WYxlecrjODN/rusRO0Irdqldkg5wuKg61oZZlc0e6VbWTA4wNWjctaXzv5WpBTzKugGQdqEIYwUHDFQakWOz9v1PZ9nGoO569ZsbOQWHvXYNRVS6ardQ9QF5kIHCWj2O7RDSZCaMnWopbNGPL7CJuklPglJVD+veZOPkTGk2jgB4ol0VQr/9rPKgHNrFfQHZa/kPIJjyAwI3KqVpgqyoreE19hYxC/N9QWfRa5wyQfvPSWMReRfdNGmUjPn+PaFKYx7KMrDaBImKTL9faWxF11LoZDJ4BV281v+lizcJbgcQOjvVSEfp0UbgHx+Kw3OKqwBPb78z1E2643V+6gXUmb3xYOWE5MDYBpZaj3TlpSqonJj7Id7SgEKF8CEviRnN9ziWiiSSxZOHrQJ1PgoLTXyoQJv9NvSHwzALIEC4qqgxsqj7GJQfeldnzUuv9oNFuqHUmG+WKDfZTt0hik/2vnOKDmglfTKA0NGUpm606gtwclnrBwug02PZbnKTMahxlaNVlIKPHz9rJCVNyfCqwJBgeqjHzkBCA/EHG8Wg/uqfxHgyBOZftD+EBW/iY6CvkhPDs1VPoURMRPzyXgfo+YF53pvTsQE6T/HVAl0f8ciLR0yBMhRoWSCUsduwoO0X2Oq3QKMSuUcY0mm8bQpGuIH9ksFxIG+E32hn/mVIN/eSenPff4A4ZDthNinz0IwAU26OvK4BimwGRH+wuuLuSlYzlw2dLmOp4h70hDUmwiBNJCU0Wtcgp0CEi8uCrgDaP43PlQOVvtYP+rzxmkzJ8WvytTdIbFUq/MpeU/2WJEr7rau6afxI6dRnn/mZVna/ylr2lXzn8g1oTCxbiB4vVmOJt4Y6DW3gIDhkkVo9dDLBBQRJ5olczopsdmAXxlpgfhwSMVkeJHUs2JFX10fS6bDD14wgOrohZYTgIWkI4LDIG8BZNZYabAeaijMlKszqwR/t1ZeKjcZB9azBZ9a1oBb8Wgt9w6UHXrcKtbglYXZysn2IlGXheBRG42WgegLPWvpwEqm+h7gUCbFFQ8L8QAze5J+yG0UGyANXw8Xa9SqcCE85hWvKWC3FSJ2S5582rW9pdhFVegYFlnHRxR+tviLJSeB9aBPsckLCnL0w2iF3ZTFkps1Y1n2f0v/nFaIZfkGrs+BLfiOQSTptb65WZWyKY5SfPJs3FLDPU33ecYaMiRpKcFUa8MyBX9QJpCInTYdeB6TG/xTEe57zWFeLwBlukZ8do1hDLk0330lbo2dFhzrNwN5Ky7pAy1Aru8c6B++YlvjOIahY8Aq3OqxyO8Y23NwSooUqRIc4/ss0u1d5fUVZpwzyz5oMByM5pY/glJyRsVP6pUrCJNASwZoNk3m7Kxrla71C3ZIoMDFPjPwEfnG/RLFTbsjdBNOnGVEH0N1B8/WsO29bdU0EcUhby1taN/um+LIcj5Fn87CWBjly43qtHk5tIYs+QrhUKFv0+5wmvwKRPZVUApM2nTAncQ6/QBj25g3TsQL9wl5GwHSTRuo6LBnqzig29dSZtsgjGpjoxePpoc/MuDIDFte7bO5JGgGx+lL/kF+0q/98IYeBtZefSQaCfPq/p3pXQDiKtFe5Fo5qdSx0bQk3P2W1tWKCljH+3YJwZy7jMjTnukCNbkfdbr4ZvsldGqKu/x8Y+4ePTJCcf5/zIYLZb8wNMd44oGj5m8pfCwF7xQ686+XmJLH5r8M7AH+4fTLtMXNRpWzCnwmm2sDK3LO7CVhHGqRz5RuKte/l0qikW4C9Xz9X7/XRjvVlZbbY7NK/Y3xxmYXv4loRVrla304j0+XHklXCZegLP9KVlg9Ge5dqUZUti0O0Jxr2Balah0c3hv4SAWRX18HY7M64zjTzQkWNk/4DIwztFsxaP+rNhFFx17ra9r0ZEvjQyRl/K7LyZ0G1AeQICTf5DLh+RrnqTybQOUhrfK/M4MERQaoyNQresPk9q7cTdjIEw/24Urp7BHusiAiSxEKrlDHMrpbXuouRGdOoqB6Jv6OpVzyS68N9ZvInIx5KPXlEFPH0RAYhBU2oSY93E3VJqwaOttjrS4H9mxDEhxOKCo8FrdVIV+9MJiShYjj44Prs8UBA4apB77nCu0rJE/ntEiDvYPMscGzA6/BvJhwcJvLlpfTM+WQJKcfqfb27CPYJu1gQC6HEmwBAXHTQm6br3Xv8XlvMDagaKREkWpSZTEx7NzBr8vOkbUeEis+kUz4W45iuUw88Qo9QyEHP/TUp6r7VtpI19//PEKPYhyxb4bc1v04pJ3g1uWfM+HMjXUOrjHypkPaJA1eRVIYgYhrfJOM7BM9oPNa7C0X/8rJyX0bawTOUnNhGyYfArSDLvqcxASSbT44jJu/p4cA1izJs1g+4y/pb/TFpmGXz6f7jRix2Ehd5uxO72z0vcjIs4TMymsuiY0f5uuzmxN4+/oKzNV7PZqv5ExLVgWlO4p9216kZWHm/cNXiaRzGkzu17R1IZrEiu9mFbAQACKpJSJsf4BtoqKLTnxZtTJuix6d/HTAa0kwKyMYDuLQOnpV+Z+YDiswCLEtIfVgFur301Rcj2JRTrlcNKoGU+cuWCnXQCzkHdw3QGT6MotNwTWF/qyKYJmMSXPoSSn2Hyb5yg2HUTTvggD65bQzqYGrkDC/mw1wtLTnuZgUq/uufy9mvhtcIH1trygEEdpKoIawJA0LrzrYXRyUTu+EwHgYwpLMjqBY2RTIP5wZQ8IVxfsOzYPbtMCohTrtx+XsWlvHJUFfYbXJb0EI1Qg73sZmZuPYmMbM0jhkYWcC6TdauWwYAFx4CxmaVoL+9bOHZcVAZypVW4U5Bx9SyFrksWl1BhXUa22k2SljRzuCtEBX/FPqG4nv5IQhoPmyxnj542LqoTfWfqNwHI8NCtpxiIa5W2COFvmo9EixsHxcq+I7jjM+puN+ObmOFKwX1b9f1INKx12+vzKXthwS0l9Z1L4F1Mbc4BNoIwmLKnzhQ7MnQmKds/yUfs2dLG9HdWL9p413jLQenhRlfhg0b1M+kcjbOD4oC5hgvlS9Hr/5+FumKtpgaq2v0WwisIkIfiff3i1OL0hZRWreG+GnFnmKqVQ9GHWUtuKHmSq4/2mQOzwkfKasvsqGHd4UIjMc6lf1dgVEBrQMiSIIw4BFQ3d1BM9Pm/DDZdJOL/Htt2gTAxZfXkYYh+jmHAC+giAz8KUx8XpwcONppihHglOAgh4maqR4+gWISh8mpf1RcQxKuM4BbPfrJeeMbDKjjnqzJOB5fEA==,iv:7ObL15TI4fzVmnXi/cwFs4HLDJ0NH5IIeZnYwdhY8mo=,tag:vKju4lziBmciCyNgTUB6Mw==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4b0xPVTIxajhEa3QrczhM\n        OTFHNG16ZEwrUWVZUVAyR0JxU0tGVVRvNVQ4Cms1dkZjb3l5ZXFRTGhYT1NnaG5w\n        M2dWQi9lTzBGT0F6Q0ptd0dtalZUeGsKLS0tIGk2dDkzYTBXSmdTLzZNSzY5U0o2\n        cW9EdGFyMGpjQUlZeVlEdVRGM2FxamMKeDR1M86D3WoAVwWkjXVi5V/vTOZpQsZv\n        wfadn8FhNqneQKUshQFw8rR4Jpr+NEBtRBBq2Z3JyASoEMzXql5qpw==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2026-02-28T11:58:11Z\"\n  mac: ENC[AES256_GCM,data:/kMPexoeMlEc2I9mL0MqrogoVfFRmmo1kmxGEfipXENzILsnc33bRpYZYgwB5GqeCkMy82ZUlC1X355G/y8gLAGZTT76Yzi0UFv1/3wDCKWsF0OGKzj5tkGOI/UDdMt4fzgXWKt6pKaFEMZDpplAG1lmg6pacswkDQn6fuS+lBs=,iv:KPzK1F9bImkA5eG2Ff21Senk3Dc3HULaNjaR+71+hvc=,tag:l17JN3ejB2e0+u3cdof0KQ==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.12.1\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/enemy-territory/app/udproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/udproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: UDPRoute\nmetadata:\n  name: enemy-territory\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: enemy-territory\n  rules:\n    - backendRefs:\n        - name: enemy-territory\n          port: 27960\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/enemy-territory/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: enemy-territory\n  namespace: game-servers\nspec:\n  path: \"./apps/base/game-servers/enemy-territory/app\"\n  wait: true\n  dependsOn:\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: enemy-territory\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: game-servers\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/config/geysermc.yaml",
    "content": "# --------------------------------\n# Geyser Configuration File\n#\n# A bridge between Minecraft: Bedrock Edition and Minecraft: Java Edition.\n#\n# GitHub: https://github.com/GeyserMC/Geyser\n# Discord: https://discord.gg/geysermc\n# Wiki: https://wiki.geysermc.org/\n#\n# NOTICE: See https://wiki.geysermc.org/geyser/setup/ for the setup guide. Many video tutorials are outdated.\n# In most cases, especially with server hosting providers, further hosting-specific configuration is required.\n# --------------------------------\n\nbedrock:\n  # The IP address that will listen for connections.\n  # Generally, you should only uncomment and change this if you want to limit what IPs can connect to your server.\n  #address: 0.0.0.0\n  # The port that will listen for connections\n  port: 19132\n  # Some hosting services change your Java port everytime you start the server and require the same port to be used for Bedrock.\n  # This option makes the Bedrock port the same as the Java port every time you start the server.\n  # This option is for the plugin version only.\n  clone-remote-port: false\n  # The MOTD that will be broadcasted to Minecraft: Bedrock Edition clients. This is irrelevant if \"passthrough-motd\" is set to true\n  # If either of these are empty, the respective string will default to \"Geyser\"\n  motd1: \"Geyser\"\n  motd2: \"Welcome to Minecraft on Kubernetes!\"\n  # The Server Name that will be sent to Minecraft: Bedrock Edition clients. This is visible in both the pause menu and the settings menu.\n  server-name: \"world\"\n  # How much to compress network traffic to the Bedrock client. The higher the number, the more CPU usage used, but\n  # the smaller the bandwidth used. Does not have any effect below -1 or above 9. Set to -1 to disable.\n  compression-level: 6\n  # The port to broadcast to Bedrock clients with the MOTD that they should use to connect to the server.\n  # DO NOT uncomment and change this unless Geyser runs on a different internal port than the one that is used to connect.\n  # broadcast-port: 19132\n  # Whether to enable PROXY protocol or not for clients. You DO NOT WANT this feature unless you run UDP reverse proxy\n  # in front of your Geyser instance.\n  enable-proxy-protocol: false\n  # A list of allowed PROXY protocol speaking proxy IP addresses/subnets. Only effective when \"enable-proxy-protocol\" is enabled, and\n  # should really only be used when you are not able to use a proper firewall (usually true with shared hosting providers etc.).\n  # Keeping this list empty means there is no IP address whitelist.\n  # IP addresses, subnets, and links to plain text files are supported.\n  #proxy-protocol-whitelisted-ips: [ \"127.0.0.1\", \"172.18.0.0/16\", \"https://example.com/whitelist.txt\" ]\nremote:\n  # The IP address of the remote (Java Edition) server\n  # If it is \"auto\", for standalone version the remote address will be set to 127.0.0.1,\n  # for plugin versions, it is recommended to keep this as \"auto\" so Geyser will automatically configure address, port, and auth-type.\n  # Leave as \"auto\" if floodgate is installed.\n  address: auto\n  # The port of the remote (Java Edition) server\n  # For plugin versions, if address has been set to \"auto\", the port will also follow the server's listening port.\n  port: 25565\n  # Authentication type. Can be offline, online, or floodgate (see https://github.com/GeyserMC/Geyser/wiki/Floodgate).\n  # For plugin versions, it's recommended to keep the `address` field to \"auto\" so Floodgate support is automatically configured.\n  # If Floodgate is installed and `address:` is set to \"auto\", then \"auth-type: floodgate\" will automatically be used.\n  auth-type: online\n  # Whether to enable PROXY protocol or not while connecting to the server.\n  # This is useful only when:\n  # 1) Your server supports PROXY protocol (it probably doesn't)\n  # 2) You run Velocity or BungeeCord with the option enabled in the proxy's main config.\n  # IF YOU DON'T KNOW WHAT THIS IS, DON'T TOUCH IT!\n  use-proxy-protocol: false\n  # Forward the hostname that the Bedrock client used to connect over to the Java server\n  # This is designed to be used for forced hosts on proxies\n  forward-hostname: false\n\n# Floodgate uses encryption to ensure use from authorised sources.\n# This should point to the public key generated by Floodgate (BungeeCord, Spigot or Velocity)\n# You can ignore this when not using Floodgate.\n# If you're using a plugin version of Floodgate on the same server, the key will automatically be picked up from Floodgate.\nfloodgate-key-file: key.pem\n\n# For online mode authentication type only.\n# Stores a list of Bedrock players that should have their Java Edition account saved after login.\n# This saves a token that can be reused to authenticate the player later. This does not save emails or passwords,\n# but you should still be cautious when adding to this list and giving others access to this Geyser instance's files.\n# Removing a name from this list will delete its cached login information on the next Geyser startup.\n# The file that tokens will be saved in is in the same folder as this config, named \"saved-refresh-tokens.json\".\nsaved-user-logins:\n  - ThisExampleUsernameShouldBeLongEnoughToNeverBeAnXboxUsername\n  - ThisOtherExampleUsernameShouldAlsoBeLongEnough\n\n# Specify how many seconds to wait while user authorizes Geyser to access their Microsoft account.\n# User is allowed to disconnect from the server during this period.\npending-authentication-timeout: 120\n\n# Bedrock clients can freeze when opening up the command prompt for the first time if given a lot of commands.\n# Disabling this will prevent command suggestions from being sent and solve freezing for Bedrock clients.\ncommand-suggestions: true\n\n# The following three options enable \"ping passthrough\" - the MOTD, player count and/or protocol name gets retrieved from the Java server.\n# Relay the MOTD from the remote server to Bedrock players.\npassthrough-motd: true\n# Relay the player count and max players from the remote server to Bedrock players.\npassthrough-player-counts: true\n# Enable LEGACY ping passthrough. There is no need to enable this unless your MOTD or player count does not appear properly.\n# This option does nothing on standalone.\nlegacy-ping-passthrough: false\n# How often to ping the remote server, in seconds. Only relevant for standalone or legacy ping passthrough.\n# Increase if you are getting BrokenPipe errors.\nping-passthrough-interval: 3\n\n# Whether to forward player ping to the server. While enabling this will allow Bedrock players to have more accurate\n# ping, it may also cause players to time out more easily.\nforward-player-ping: false\n\n# Maximum amount of players that can connect. This is only visual at this time and does not actually limit player count.\nmax-players: 100\n\n# If debug messages should be sent through console\ndebug-mode: false\n\n# Allow a fake cooldown indicator to be sent. Bedrock players otherwise do not see a cooldown as they still use 1.8 combat.\n# Please note: if the cooldown is enabled, some users may see a black box during the cooldown sequence, like below:\n# https://cdn.discordapp.com/attachments/613170125696270357/957075682230419466/Screenshot_from_2022-03-25_20-35-08.png\n# This can be disabled by going into Bedrock settings under the accessibility tab and setting \"Text Background Opacity\" to 0\n# This setting can be set to \"title\", \"actionbar\" or \"false\"\nshow-cooldown: title\n\n# Controls if coordinates are shown to players.\nshow-coordinates: true\n\n# Whether Bedrock players are blocked from performing their scaffolding-style bridging.\ndisable-bedrock-scaffolding: false\n\n# If set, when a Bedrock player performs any emote, it will swap the offhand and mainhand items, just like the Java Edition keybind\n# There are three options this can be set to:\n# disabled - the default/fallback, which doesn't apply this workaround\n# no-emotes - emotes will NOT be sent to other Bedrock clients and offhand will be swapped. This effectively disables all emotes from being seen.\n# emotes-and-offhand - emotes will be sent to Bedrock clients and offhand will be swapped\nemote-offhand-workaround: \"disabled\"\n\n# The default locale if we dont have the one the client requested. Uncomment to not use the default system language.\n# default-locale: en_us\n\n# Specify how many days images will be cached to disk to save downloading them from the internet.\n# A value of 0 is disabled. (Default: 0)\ncache-images: 0\n\n# Allows custom skulls to be displayed. Keeping them enabled may cause a performance decrease on older/weaker devices.\nallow-custom-skulls: true\n\n# The maximum number of custom skulls to be displayed per player. Increasing this may decrease performance on weaker devices.\n# Setting this to -1 will cause all custom skulls to be displayed regardless of distance or number.\nmax-visible-custom-skulls: 128\n\n# The radius in blocks around the player in which custom skulls are displayed.\ncustom-skull-render-distance: 32\n\n# Whether to add any items and blocks which normally does not exist in Bedrock Edition.\n# This should only need to be disabled if using a proxy that does not use the \"transfer packet\" style of server switching.\n# If this is disabled, furnace minecart items will be mapped to hopper minecart items.\n# Geyser's block, item, and skull mappings systems will also be disabled.\n# This option requires a restart of Geyser in order to change its setting.\nadd-non-bedrock-items: true\n\n# Bedrock prevents building and displaying blocks above Y127 in the Nether.\n# This config option works around that by changing the Nether dimension ID to the End ID.\n# The main downside to this is that the entire Nether will have the same red fog rather than having different fog for each biome.\nabove-bedrock-nether-building: false\n\n# Force clients to load all resource packs if there are any.\n# If set to false, it allows the user to connect to the server even if they don't\n# want to download the resource packs.\nforce-resource-packs: true\n\n# Allows Xbox achievements to be unlocked.\nxbox-achievements-enabled: false\n\n# Whether player IP addresses will be logged by the server.\nlog-player-ip-addresses: true\n\n# Whether to alert the console and operators that a new Geyser version is available that supports a Bedrock version\n# that this Geyser version does not support. It's recommended to keep this option enabled, as many Bedrock platforms\n# auto-update.\nnotify-on-new-bedrock-update: true\n\n# Which item to use to mark unavailable slots in a Bedrock player inventory. Examples of this are the 2x2 crafting grid while in creative,\n# or custom inventory menus with sizes different from the usual 3x9. A barrier block is the default item.\nunusable-space-block: minecraft:barrier\n\n# bStats is a stat tracker that is entirely anonymous and tracks only basic information\n# about Geyser, such as how many people are online, how many servers are using Geyser,\n# what OS is being used, etc. You can learn more about bStats here: https://bstats.org/.\n# https://bstats.org/plugin/server-implementation/GeyserMC\nmetrics:\n  # If metrics should be enabled\n  enabled: true\n  # UUID of server, don't change!\n  uuid: 9df3bf45-81e3-47d4-a334-539311a55da7\n\n# ADVANCED OPTIONS - DO NOT TOUCH UNLESS YOU KNOW WHAT YOU ARE DOING!\n\n# Geyser updates the Scoreboard after every Scoreboard packet, but when Geyser tries to handle\n# a lot of scoreboard packets per second can cause serious lag.\n# This option allows you to specify after how many Scoreboard packets per seconds\n# the Scoreboard updates will be limited to four updates per second.\nscoreboard-packet-threshold: 20\n\n# Allow connections from ProxyPass and Waterdog.\n# See https://www.spigotmc.org/wiki/firewall-guide/ for assistance - use UDP instead of TCP.\nenable-proxy-connections: false\n\n# The internet supports a maximum MTU of 1492 but could cause issues with packet fragmentation.\n# 1400 is the default.\nmtu: 1400\n\n# Whether to connect directly into the Java server without creating a TCP connection.\n# This should only be disabled if a plugin that interfaces with packets or the network does not work correctly with Geyser.\n# If enabled on plugin versions, the remote address and port sections are ignored\n# If disabled on plugin versions, expect performance decrease and latency increase\nuse-direct-connection: true\n\n# Whether Geyser should attempt to disable compression for Bedrock players. This should be a benefit as there is no need to compress data\n# when Java packets aren't being handled over the network.\n# This requires use-direct-connection to be true.\ndisable-compression: true\n\nconfig-version: 4\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: minecraft\n      version: 5.1.3\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n    serviceAnnotations:\n      lbipam.cilium.io/ips: ${CLUSTER_LB_MINECRAFT}\n    extraVolumes:\n      - volumeMounts:\n          - name: geyser-config-volume\n            mountPath: /data/plugins/Geyser-Spigot/config.yml\n            subPath: config.yml\n        volumes:\n          - name: geyser-config-volume\n            configMap:\n              name: geysermc-config\n  valuesFrom:\n    - kind: ConfigMap\n      name: minecraft-values\n    - kind: Secret\n      name: minecraft-secret-values\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: minecraft-map\n  namespace: game-servers\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'map.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: minecraft\n          port: 8100\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - tcproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n  - secret.enc.age.yaml\n\nconfigMapGenerator:\n  - name: minecraft-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n  - name: geysermc-config\n    namespace: game-servers\n    files:\n      - config.yml=./config/geysermc.yaml\n\nsecretGenerator:\n  - name: minecraft-secret-values\n    namespace: game-servers\n    files:\n      - values.yaml=values.enc.age.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/values/extraVolumes/volumes/configMap/name\n        kind: HelmRelease\n  - kind: Secret\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft-ceph\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: geyser-data-ceph\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 1Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft\n  namespace: game-servers\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: geyser-data\n  namespace: game-servers\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 1Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: minecraft\nspec:\n  sourcePVC: minecraft-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: minecraft-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: minecraft-rcon\n  namespace: game-servers\ntype: Opaque\nstringData:\n  rcon-password: ENC[AES256_GCM,data:gAYP5VK/26E=,iv:iWNuUfWkT4yKDXzaEanSQMKmr8vv3D2ubhuvfzCeM7k=,tag:ogs1Mzvgh15s3pIzF2RaDQ==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6ZVFOVUcrYkgyTU04QUpx\n        ODVIa3RodFhLdHM2aVVHQWRLWVJjY1d4cjNRCnlLampjSVNiQm9hWXJoY2JVNHN6\n        UlVEbVAraXN3Yi9ZZVlXWFR6dHVXbFEKLS0tIDlGdThUejVIeS9pZG84bDJUZnpi\n        L21jSjZYQTNPcUxULzRhN0g2NXFWemcKcrv10p3PQrvN4tEH1/gz5M0myy0eDLSj\n        2Ch+miySQRbW/IYe+bTQVybCsv0CdlCEtNzUc5VzVtcZnWn9tl9Mxw==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2026-03-04T21:37:14Z\"\n  mac: ENC[AES256_GCM,data:rsRoA82BiXT1kgxcFxh+pkklLGj60BdXY1ps3YViOZfsih5QCnQuJ2fsh+xDwtaJQs7x1jzUIXR/GW5TIjyyBI+wdd4eA2sp41nCTMyDd4D+PONvdM4GxVVFim09cDa+43QXwZYwH4h5RvPCipLSLPGY43cl1k187ugbN83dZNc=,iv:34f35VFTSHOucueZW0bZJFQ9ZhDh0rBMnPGTSy8c6Do=,tag:mDDH4GPCGcB1rllhZ3Tkug==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.12.1\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/tcproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/tcproute_v1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: TCPRoute\nmetadata:\n  name: minecraft-java\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: minecraft-java\n  rules:\n    - backendRefs:\n        - name: minecraft\n          port: 25565\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/values.enc.age.yaml",
    "content": "minecraftServer:\n  ops: .Unholy050,Unholy050,\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDV24xaTJ5UEFFQ2FyeW1V\n        V1dWVnA0bjhjYmFaTE1mTXRnSkhob2JWR0dBCjJPandVYWZJTkQ5UEU4WWJSSTR6\n        M1hFQW1LWHVKRmw1dFhVWXZOOUNmcnMKLS0tIGQ1akZheUlDQlhkbFF6Y0J4ZVRV\n        aWZBd2hKZC9PTmJTMzdyUmZ6VUVwZ0kKS9hdfLUz5SeCop8Ij1TwsBZRGUflMuBe\n        +cZPabbwZGGeEVKj6mzgH54DFovJJQns5xU6hmZTxzUszEDQtimHzA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2026-03-05T02:58:26Z\"\n  mac: ENC[AES256_GCM,data:uvVfuCVRWvUEN778j4i+lTE0d9RH9jsLVqsr3gqt7C8NoH32P2ZR0KrPRWrXUihR1bfeKg90rMn2Yb7cG2i4vyBhgOvAdhE/6MxVLfpsC2e5hfZaLR4DKmSvu6+RAj2QwzKoYfPJCFUbiUmf2ulmMWqhLzDh/o7Bs+xSpRljjUc=,iv:JcO90Cf9fGaTnFAa49xDltLLBwNSqfBuBep+JJCcp5g=,tag:Vlzw7Pjr+iztO/D9oY25iw==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.12.1\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/values.yaml",
    "content": "extraEnv:\n  TZ: \"${CLUSTER_TIMEZONE}\"\n  # Force IPv4 stack to fix RCON connectivity issues\n  JVM_OPTS: \"-Djava.net.preferIPv4Stack=true\"\n\nminecraftServer:\n  serverName: Wildfire Minecraft Server\n  eula: \"TRUE\"\n  type: PAPER\n  version: LATEST\n  # REQUIRED: Must use for spigot plugins that are listed as available via external sites\n  pluginUrls:\n    - https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot\n    - https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot\n  spigetResources:\n    - 34315 # Vault\n  modrinth:\n    projects:\n      - multiverse-core\n      - essentialsx\n      - worldguard\n      - worldedit\n      - bluemap\n      - viaversion\n      - viarewind\n      - viabackwards\n      - luckperms\n    downloadDependencies: required\n    allowedVersionType: beta\n  resourcePackUrl: https://download.geysermc.org/v2/projects/geyseroptionalpack/versions/latest/builds/latest/downloads/geyseroptionalpack\n  maxPlayers: 10\n  maxTickTime: -1\n  gameMode: survival\n  hardcore: false\n  pvp: false\n  worldSaveName: world\n  onlineMode: true\n  rcon:\n    enabled: true\n    existingSecret: minecraft-rcon\n    secretKey: rcon-password\n  motd: \"Welcome to Minecraft on Kubernetes!\"\n  playerIdleTimeout: 10\n  memory: 8192M\n  cheats: true\n  enableLanVisibility: true\n  defaultPermission: operator\n  enableSSH: true\n  serviceType: LoadBalancer\n  extraPorts:\n    - name: geysermc\n      containerPort: 19132\n      protocol: UDP\n      service:\n        enabled: true\n        embedded: true\n        port: 19132\n    - name: bluemap\n      containerPort: 8100\n      protocol: TCP\n      service:\n        enabled: true\n        embedded: true\n        port: 8100\n  overrideServerProperties: true\n  removeOldMods: true\n\ntolerations:\n  - key: \"node-role.kubernetes.io/control-plane\"\n    operator: \"Exists\"\n    effect: \"NoSchedule\"\n\naffinity:\n  nodeAffinity:\n    requiredDuringSchedulingIgnoredDuringExecution:\n      nodeSelectorTerms:\n        - matchExpressions:\n            - key: \"node-role.kubernetes.io/control-plane\"\n              operator: \"Exists\"\n\nresources:\n  requests:\n    memory: 8Gi\n    cpu: 4\n\npersistence:\n  dataDir:\n    enabled: true\n    existingClaim: minecraft-ceph\n\npodSecurityContext:\n  runAsUser: 1000\n  runAsGroup: 1000\n  runAsNonRoot: true\n  fsGroup: 1000\n  seccompProfile:\n    type: RuntimeDefault\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: minecraft-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: minecraft-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft\n  namespace: game-servers\nspec:\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  path: \"./apps/base/game-servers/minecraft/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft-bedrock\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: minecraft-bedrock\n      version: 2.9.0\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n  valuesFrom:\n    - kind: ConfigMap\n      name: mincraft-bedrock-values\n    - kind: Secret\n      name: mincraft-bedrock-secret-values\n  postRenderers:\n    # IMPORTANT: Does not work with multus when using hostNetwork: true\n    - kustomize:\n        patches:\n          - target:\n              version: v1\n              kind: Deployment\n              name: minecraft-bedrock-minecraft-bedrock\n            patch: |\n              - op: add\n                path: /spec/template/spec/hostNetwork\n                value: true\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - udproute.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n\nconfigMapGenerator:\n  - name: mincraft-bedrock-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n\nsecretGenerator:\n  - name: mincraft-bedrock-secret-values\n    namespace: game-servers\n    files:\n      - values.yaml=values.enc.age.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n  - kind: Secret\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft-bedrock-ceph\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft-bedrock\n  namespace: game-servers\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: minecraft-bedrock\nspec:\n  sourcePVC: minecraft-bedrock-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 2000\n      fsGroup: 2000\n    parallelism: 2\n    repository: minecraft-bedrock-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/udproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/udproute_1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: UDPRoute\nmetadata:\n  name: minecraft-bedrock\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: minecraft-bedrock\n  rules:\n    - backendRefs:\n        - name: minecraft\n          port: 19132\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/values.enc.age.yaml",
    "content": "minecraftServer:\n  passwordSSH: password\n  enableSSH: true\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQYmVaRDNFY2lNY3N4eGIv\n        dGttVGxaUWVJdk40cnl6NkRucWF6UFl5STFVCjdZUDdjWG5nM3F3Z1ZqVTRtbUN0\n        N1BCd2Y5WERVa0JnNUc3ekczQVVLTHcKLS0tIHNIUnBZZHVmaW04TitkL2tEVjZE\n        RVQybDREdjZFYjZMR0FjZXEvN3hCR1EKwN+/60aLJRJ1zS4iMOIOIc8rZhgqDVIZ\n        DdmYa9uXhJd8Ejqvh8jgMxaohzQHPV1gnThKRpHFRD8a8yN5IkBDtA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:21:04Z\"\n  mac: ENC[AES256_GCM,data:aGJYrzWNfkzXAGabdvN3nHcx6X/7+C9p+hJA0cZoHeDffO3LUneIJmHODAwkGeG3BJkt7g16u8cM/gRIO2Rc5mME7xwokVdz19s4RIIK2fOO7v5dkPTFBNC8EpmRhAQtdMNSMJb8vQoSZujYwutOsWGFv9TdO5aM+Mr2Wb2zluI=,iv:sCxGx8AzReG3EQlQZgOaG03No2tb83YhAuuCJ3lv72o=,tag:CYvm53Hliew+ue04urcFNA==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/values.yaml",
    "content": "image:\n  repository: itzg/minecraft-bedrock-server\n  tag: latest\nminecraftServer:\n  serverName: Bedrock Minecraft Server\n  levelName: Wildfire\n  serverPort: 19131\n  eula: \"TRUE\"\n  version: LATEST\n  difficulty: peaceful\n  maxPlayers: 10\n  gameMode: survival\n  playerIdleTimeout: 10\n  cheats: true\n  enableLanVisibility: true\n  defaultPermission: operator\n  serviceType: LoadBalancer\n  # TODO: Consider disabling if Microsoft login failure occurs;\n  # Check accounts against Minecraft account service.\n  onlineMode: false\npodAnnotations:\n  k8s.v1.cni.cncf.io/networks: network-system/wifi-network\npersistence:\n  dataDir:\n    enabled: true\n    existingClaim: minecraft-bedrock-ceph\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: minecraft-bedrock-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: minecraft-bedrock-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft-bedrock\n  namespace: game-servers\nspec:\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  path: \"./apps/base/game-servers/minecraft-bedrock/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft-bedrock\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft-bedrock-broadcaster\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: minecraft-bedrock\n      version: 2.9.0\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n  valuesFrom:\n    - kind: ConfigMap\n      name: minecraft-bedrock-broadcaster-values\n    - kind: Secret\n      name: minecraft-bedrock-broadcaster-secret-values\n  postRenderers:\n    # IMPORTANT: Does not work with multus when using hostNetwork: true\n    - kustomize:\n        patches:\n          - target:\n              version: v1\n              kind: Deployment\n              name: minecraft-bedrock-broadcaster-minecraft-bedrock\n            patch: |\n              - op: add\n                path: /spec/template/spec/hostNetwork\n                value: true\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - udproute.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n\nconfigMapGenerator:\n  - name: minecraft-bedrock-broadcaster-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n\nsecretGenerator:\n  - name: minecraft-bedrock-broadcaster-secret-values\n    namespace: game-servers\n    files:\n      - values.yaml=values.enc.age.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n  - kind: Secret\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft-bedrock-broadcaster-ceph\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft-bedrock-broadcaster\n  namespace: game-servers\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: minecraft-bedrock-broadcaster\nspec:\n  sourcePVC: minecraft-bedrock-broadcaster-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 2000\n      fsGroup: 2000\n    parallelism: 2\n    repository: minecraft-bedrock-broadcaster-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/udproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/udproute_1alpha2.json\napiVersion: gateway.networking.k8s.io/v1alpha2\nkind: UDPRoute\nmetadata:\n  name: minecraft-bedrock-broadcaster\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\n    external-dns.alpha.kubernetes.io/hostname: play.bedrockbroadcaster.com\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: minecraft-bedrock-broadcaster\n  rules:\n    - backendRefs:\n        - name: minecraft-bedrock-broadcaster\n          port: 19132\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/values.enc.age.yaml",
    "content": "minecraftServer:\n  passwordSSH: password\n  enableSSH: true\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQYmVaRDNFY2lNY3N4eGIv\n        dGttVGxaUWVJdk40cnl6NkRucWF6UFl5STFVCjdZUDdjWG5nM3F3Z1ZqVTRtbUN0\n        N1BCd2Y5WERVa0JnNUc3ekczQVVLTHcKLS0tIHNIUnBZZHVmaW04TitkL2tEVjZE\n        RVQybDREdjZFYjZMR0FjZXEvN3hCR1EKwN+/60aLJRJ1zS4iMOIOIc8rZhgqDVIZ\n        DdmYa9uXhJd8Ejqvh8jgMxaohzQHPV1gnThKRpHFRD8a8yN5IkBDtA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:21:04Z\"\n  mac: ENC[AES256_GCM,data:aGJYrzWNfkzXAGabdvN3nHcx6X/7+C9p+hJA0cZoHeDffO3LUneIJmHODAwkGeG3BJkt7g16u8cM/gRIO2Rc5mME7xwokVdz19s4RIIK2fOO7v5dkPTFBNC8EpmRhAQtdMNSMJb8vQoSZujYwutOsWGFv9TdO5aM+Mr2Wb2zluI=,iv:sCxGx8AzReG3EQlQZgOaG03No2tb83YhAuuCJ3lv72o=,tag:CYvm53Hliew+ue04urcFNA==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/values.yaml",
    "content": "image:\n  repository: itzg/minecraft-bedrock-server\n  tag: latest\nminecraftServer:\n  serverName: Bedrock Broadcaster Server\n  levelName: Broadcaster\n  serverPort: 19135\n  eula: \"TRUE\"\n  version: LATEST\n  difficulty: peaceful\n  maxPlayers: 10\n  gameMode: survival\n  playerIdleTimeout: 10\n  cheats: true\n  enableLanVisibility: true\n  defaultPermission: operator\n  serviceType: LoadBalancer\n  # TODO: Consider disabling if Microsoft login failure occurs;\n  # Check accounts against Minecraft account service.\n  onlineMode: false\n  texturepackRequired: true\npodAnnotations:\n  k8s.v1.cni.cncf.io/networks: network-system/wifi-network\npersistence:\n  dataDir:\n    enabled: true\n    existingClaim: minecraft-bedrock-broadcaster-ceph\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: minecraft-bedrock-broadcaster-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: minecraft-bedrock-broadcaster-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-bedrock-broadcaster/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft-bedrock-broadcaster\n  namespace: game-servers\nspec:\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  path: \"./apps/base/game-servers/minecraft-bedrock-broadcaster/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft-bedrock-broadcaster\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-pixelmon/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft-pixelmon\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: minecraft-bedrock\n      version: 2.9.0\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n  valuesFrom:\n    - kind: ConfigMap\n      name: minecraft-pixelmon-values\n  postRenderers:\n    - kustomize:\n        patches:\n          - target:\n              version: v1\n              kind: Deployment\n              name: minecraft-pixelmon-minecraft-bedrock\n            patch: |\n              - op: add\n                path: /spec/template/spec/hostNetwork\n                value: true\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-pixelmon/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc-ceph.yaml\n\nconfigMapGenerator:\n  - name: minecraft-pixelmon-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-pixelmon/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-pixelmon/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft-pixelmon-ceph\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-pixelmon/app/values.yaml",
    "content": "image:\n  repository: itzg/minecraft-bedrock-server\n  tag: latest\nminecraftServer:\n  serverName: Wildfire Pixelmon Server\n  levelName: Pixelmon\n  serverPort: 19138\n  eula: \"TRUE\"\n  version: LATEST\n  difficulty: normal\n  maxPlayers: 10\n  gameMode: survival\n  playerIdleTimeout: 10\n  cheats: true\n  enableLanVisibility: true\n  defaultPermission: operator\n  serviceType: LoadBalancer\n  onlineMode: false\n  texturepackRequired: true\nextraEnv:\n  SERVER_PORT_V6: \"19139\"\ninitContainers:\n  - name: install-pokedrock\n    image: alpine:latest\n    securityContext:\n      runAsUser: 0\n      runAsNonRoot: false\n    command:\n      - /bin/sh\n      - -c\n      - |\n        set -e\n        apk add --no-cache curl unzip jq\n\n        ADDON_URL=\"https://edge.forgecdn.net/files/7358/835/SERPpokedrock.mcaddon\"\n        DATA_DIR=\"/data\"\n        LEVEL_NAME=\"Pixelmon\"\n\n        # Skip if already installed\n        if [ -f \"$DATA_DIR/.serp-pokedrock-v1.29.1\" ]; then\n          echo \"SERP Pokedrock v1.29.1 already installed, skipping...\"\n          exit 0\n        fi\n\n        # Download the addon\n        echo \"Downloading SERP Pokedrock addon...\"\n        curl -L -o /tmp/addon.mcaddon \"$ADDON_URL\"\n\n        # Extract (mcaddon is a renamed zip)\n        echo \"Extracting addon...\"\n        mkdir -p /tmp/addon\n        unzip -o /tmp/addon.mcaddon -d /tmp/addon\n\n        # Extract any nested zip/mcpack files within the addon\n        find /tmp/addon -name \"*.zip\" -o -name \"*.mcpack\" | while IFS= read -r nested; do\n          echo \"Extracting nested archive: $(basename \"$nested\")\"\n          NESTED_DIR=\"/tmp/addon/$(basename \"$nested\" | sed 's/\\.[^.]*$//')\"\n          mkdir -p \"$NESTED_DIR\"\n          unzip -o \"$nested\" -d \"$NESTED_DIR\"\n          rm \"$nested\"\n        done\n\n        # Initialize pack activation files\n        echo \"[]\" > /tmp/bp.json\n        echo \"[]\" > /tmp/rp.json\n\n        # Process each manifest.json to find behavior and resource packs\n        find /tmp/addon -name \"manifest.json\" -type f | while IFS= read -r manifest; do\n          PACK_DIR=\"$(dirname \"$manifest\")\"\n          PACK_TYPE=\"$(jq -r '.modules[0].type' \"$manifest\")\"\n          PACK_UUID=\"$(jq -r '.header.uuid' \"$manifest\")\"\n          PACK_VERSION=\"$(jq -c '.header.version' \"$manifest\")\"\n          PACK_NAME=\"$(basename \"$PACK_DIR\")\"\n\n          echo \"Found pack: $PACK_NAME (type: $PACK_TYPE, uuid: $PACK_UUID)\"\n\n          if [ \"$PACK_TYPE\" = \"data\" ] || [ \"$PACK_TYPE\" = \"script\" ]; then\n            echo \"Installing behavior pack: $PACK_NAME\"\n            mkdir -p \"$DATA_DIR/behavior_packs\"\n            cp -r \"$PACK_DIR\" \"$DATA_DIR/behavior_packs/$PACK_NAME\"\n            jq --arg uuid \"$PACK_UUID\" --argjson ver \"$PACK_VERSION\" \\\n              '. + [{\"pack_id\": $uuid, \"version\": $ver}]' /tmp/bp.json > /tmp/bp_new.json\n            mv /tmp/bp_new.json /tmp/bp.json\n          elif [ \"$PACK_TYPE\" = \"resources\" ]; then\n            echo \"Installing resource pack: $PACK_NAME\"\n            mkdir -p \"$DATA_DIR/resource_packs\"\n            cp -r \"$PACK_DIR\" \"$DATA_DIR/resource_packs/$PACK_NAME\"\n            jq --arg uuid \"$PACK_UUID\" --argjson ver \"$PACK_VERSION\" \\\n              '. + [{\"pack_id\": $uuid, \"version\": $ver}]' /tmp/rp.json > /tmp/rp_new.json\n            mv /tmp/rp_new.json /tmp/rp.json\n          fi\n        done\n\n        # Activate packs for the world\n        mkdir -p \"$DATA_DIR/worlds/$LEVEL_NAME\"\n        cp /tmp/bp.json \"$DATA_DIR/worlds/$LEVEL_NAME/world_behavior_packs.json\"\n        cp /tmp/rp.json \"$DATA_DIR/worlds/$LEVEL_NAME/world_resource_packs.json\"\n\n        echo \"=== Installed behavior packs ===\"\n        cat \"$DATA_DIR/worlds/$LEVEL_NAME/world_behavior_packs.json\"\n        echo \"=== Installed resource packs ===\"\n        cat \"$DATA_DIR/worlds/$LEVEL_NAME/world_resource_packs.json\"\n\n        # Mark as installed\n        touch \"$DATA_DIR/.serp-pokedrock-v1.29.1\"\n        echo \"SERP Pokedrock addon installation complete!\"\n    volumeMounts:\n      - name: datadir\n        mountPath: /data\nstartupProbe:\n  enabled: true\n  failureThreshold: 60\n  periodSeconds: 10\nlivenessProbe:\n  initialDelaySeconds: 60\nreadinessProbe:\n  initialDelaySeconds: 60\npersistence:\n  dataDir:\n    enabled: true\n    existingClaim: minecraft-pixelmon-ceph\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-pixelmon/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft-pixelmon\n  namespace: game-servers\nspec:\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n  path: \"./apps/base/game-servers/minecraft-pixelmon/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft-pixelmon\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-proxy/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft-proxy\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: minecraft-proxy\n      version: 3.10.0\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n  valuesFrom:\n    - kind: ConfigMap\n      name: mincraft-proxy-values\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-proxy/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: game-servers\n\nresources:\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: mincraft-proxy-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-proxy/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-proxy/app/values.yaml",
    "content": "minecraftProxy:\n  type: BUNGEECORD\n  onlineMode: true\n  rcon:\n    enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-proxy/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft-proxy\n  namespace: game-servers\nspec:\n  path: \"./apps/base/game-servers/minecraft-proxy/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft-proxy\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-rcon-web/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft-rcon-web\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: rcon-web-admin\n      version: 1.2.1\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n  valuesFrom:\n    - kind: ConfigMap\n      name: minecraft-rcon-web-values\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-rcon-web/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: minecraft-rcon\n  namespace: game-servers\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'rcon.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: minecraft-rcon-web\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-rcon-web/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: game-servers\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n\nconfigMapGenerator:\n  - name: minecraft-rcon-web-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-rcon-web/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-rcon-web/app/secret.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: minecraft-rcon\n  namespace: game-servers\ntype: Opaque\nstringData:\n  rcon-password: ENC[AES256_GCM,data:gAYP5VK/26E=,iv:iWNuUfWkT4yKDXzaEanSQMKmr8vv3D2ubhuvfzCeM7k=,tag:ogs1Mzvgh15s3pIzF2RaDQ==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6ZVFOVUcrYkgyTU04QUpx\n        ODVIa3RodFhLdHM2aVVHQWRLWVJjY1d4cjNRCnlLampjSVNiQm9hWXJoY2JVNHN6\n        UlVEbVAraXN3Yi9ZZVlXWFR6dHVXbFEKLS0tIDlGdThUejVIeS9pZG84bDJUZnpi\n        L21jSjZYQTNPcUxULzRhN0g2NXFWemcKcrv10p3PQrvN4tEH1/gz5M0myy0eDLSj\n        2Ch+miySQRbW/IYe+bTQVybCsv0CdlCEtNzUc5VzVtcZnWn9tl9Mxw==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2026-03-04T21:37:14Z\"\n  mac: ENC[AES256_GCM,data:rsRoA82BiXT1kgxcFxh+pkklLGj60BdXY1ps3YViOZfsih5QCnQuJ2fsh+xDwtaJQs7x1jzUIXR/GW5TIjyyBI+wdd4eA2sp41nCTMyDd4D+PONvdM4GxVVFim09cDa+43QXwZYwH4h5RvPCipLSLPGY43cl1k187ugbN83dZNc=,iv:34f35VFTSHOucueZW0bZJFQ9ZhDh0rBMnPGTSy8c6Do=,tag:mDDH4GPCGcB1rllhZ3Tkug==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.12.1\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-rcon-web/app/values.yaml",
    "content": "# Required: When not using ingress.enabled=true then must use Loadbalancer for deployment spec to render.\nservice:\n  type: LoadBalancer\n# Required: Hack to avoid the startup scripts from determining the WS IP:PORT.\ningress:\n  enabled: true\nrconWeb:\n  isAdmin: true\n  game: minecraft\n  passwordExistingSecret: minecraft-rcon\n  passwordKey: rcon-password\n  rconHost: minecraft-rcon.game-servers.svc.cluster.local\n  rconPort: 25575\n  rconPasswordExistingSecret: minecraft-rcon\n  rconPasswordKey: \"rcon-password\"\n  serverName: \"Wildfire Minecraft Server\"\nextraEnv:\n  TZ: ${CLUSTER_TIMEZONE}\n\n\n# Required: Cannot install jq as part of startup script.\n# securityContext: {}\n  # readOnlyRootFilesystem: false\n  # allowPrivilegeEscalation: true\n\n# podSecurityContext: {}\n  # runAsUser: 1000\n  # runAsGroup: 1000\n  # runAsNonRoot: true\n  # fsGroup: 1000\n  # seccompProfile:\n  #   type: RuntimeDefault\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-rcon-web/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft-rcon-web\n  namespace: game-servers\nspec:\n  dependsOn:\n    - name: minecraft\n      namespace: game-servers\n  path: \"./apps/base/game-servers/minecraft-rcon-web/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft-rcon-web\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-router/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft-router\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: mc-router\n      version: 1.5.0\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n  valuesFrom:\n    - kind: ConfigMap\n      name: mincraft-router-values\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-router/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: game-servers\n\nresources:\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: mincraft-router-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-router/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-router/app/values.yaml",
    "content": "services:\n  # Service for Minecraft client connections\n  minecraft:\n    type: LoadBalancer\n    port: 19132\n    annotations:\n      lbipam.cilium.io/ips: ${CLUSTER_LB_MINECRAFT_ROUTER}\n\nminecraftRouter:\n  debug:\n    enabled: true\n\n  # Default Minecraft server to use when mapping not found\n  defaultServer:\n    host: \"minecraft.game-servers.svc.cluster.local\"\n    port: 19132\n\n  mappings:\n    - externalHostname: \"bedrock.${CLUSTER_DOMAIN}\"\n      host: \"minecraft.game-servers.svc.cluster.local\"\n      port: 19132\n    - externalHostname: \"java.${CLUSTER_DOMAIN}\"\n      host: \"minecraft.game-servers.svc.cluster.local\"\n      port: 25565\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-router/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft-router\n  namespace: game-servers\nspec:\n  path: \"./apps/base/game-servers/minecraft-router/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft-router\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-witherstorm/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app minecraft-witherstorm\n  namespace: game-servers\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: minecraft-bedrock\n      version: 2.9.0\n      sourceRef:\n        kind: HelmRepository\n        name: minecraft-server-charts\n        namespace: flux-system\n      interval: 5m\n  values:\n    fullnameOverride: *app\n  valuesFrom:\n    - kind: ConfigMap\n      name: minecraft-witherstorm-values\n  postRenderers:\n    - kustomize:\n        patches:\n          - target:\n              version: v1\n              kind: Deployment\n              name: minecraft-witherstorm-minecraft-bedrock\n            patch: |\n              - op: add\n                path: /spec/template/spec/hostNetwork\n                value: true\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-witherstorm/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc-ceph.yaml\n\nconfigMapGenerator:\n  - name: minecraft-witherstorm-values\n    namespace: game-servers\n    files:\n      - values.yaml=./values.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-witherstorm/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-witherstorm/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: minecraft-witherstorm-data\n  namespace: game-servers\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-witherstorm/app/values.yaml",
    "content": "image:\n  repository: itzg/minecraft-bedrock-server\n  tag: latest\nminecraftServer:\n  serverName: Wither Storm Bedrock Server\n  levelName: WitherStorm\n  serverPort: 19136\n  eula: \"TRUE\"\n  version: LATEST\n  difficulty: normal\n  maxPlayers: 10\n  gameMode: survival\n  playerIdleTimeout: 10\n  cheats: true\n  enableLanVisibility: true\n  defaultPermission: operator\n  serviceType: LoadBalancer\n  onlineMode: false\n  texturepackRequired: true\nextraEnv:\n  SERVER_PORT_V6: \"19137\"\ninitContainers:\n  - name: install-wither-storm\n    image: alpine:latest\n    securityContext:\n      runAsUser: 0\n      runAsNonRoot: false\n    command:\n      - /bin/sh\n      - -c\n      - |\n        set -e\n        apk add --no-cache curl unzip jq\n\n        ADDON_URL=\"https://edge.forgecdn.net/files/6413/077/CWSP%20Bedrock%200.4.8.4.mcaddon\"\n        DATA_DIR=\"/data\"\n        LEVEL_NAME=\"WitherStorm\"\n\n        # Skip if already installed\n        if [ -f \"$DATA_DIR/.wither-storm-addon-v0.4.8.4\" ]; then\n          echo \"Wither Storm addon v0.4.8.4 already installed, skipping...\"\n          exit 0\n        fi\n\n        # Download the addon\n        echo \"Downloading Cracker's Wither Storm Bedrock Port addon...\"\n        curl -L -o /tmp/addon.mcaddon \"$ADDON_URL\"\n\n        # Extract (mcaddon is a renamed zip)\n        echo \"Extracting addon...\"\n        mkdir -p /tmp/addon\n        unzip -o /tmp/addon.mcaddon -d /tmp/addon\n\n        # Initialize pack activation files\n        echo \"[]\" > /tmp/bp.json\n        echo \"[]\" > /tmp/rp.json\n\n        # Process each manifest.json to find behavior and resource packs\n        find /tmp/addon -name \"manifest.json\" -type f | while IFS= read -r manifest; do\n          PACK_DIR=\"$(dirname \"$manifest\")\"\n          PACK_TYPE=\"$(jq -r '.modules[0].type' \"$manifest\")\"\n          PACK_UUID=\"$(jq -r '.header.uuid' \"$manifest\")\"\n          PACK_VERSION=\"$(jq -c '.header.version' \"$manifest\")\"\n          PACK_NAME=\"$(basename \"$PACK_DIR\")\"\n\n          echo \"Found pack: $PACK_NAME (type: $PACK_TYPE, uuid: $PACK_UUID)\"\n\n          if [ \"$PACK_TYPE\" = \"data\" ] || [ \"$PACK_TYPE\" = \"script\" ]; then\n            echo \"Installing behavior pack: $PACK_NAME\"\n            mkdir -p \"$DATA_DIR/behavior_packs\"\n            cp -r \"$PACK_DIR\" \"$DATA_DIR/behavior_packs/$PACK_NAME\"\n            jq --arg uuid \"$PACK_UUID\" --argjson ver \"$PACK_VERSION\" \\\n              '. + [{\"pack_id\": $uuid, \"version\": $ver}]' /tmp/bp.json > /tmp/bp_new.json\n            mv /tmp/bp_new.json /tmp/bp.json\n          elif [ \"$PACK_TYPE\" = \"resources\" ]; then\n            echo \"Installing resource pack: $PACK_NAME\"\n            mkdir -p \"$DATA_DIR/resource_packs\"\n            cp -r \"$PACK_DIR\" \"$DATA_DIR/resource_packs/$PACK_NAME\"\n            jq --arg uuid \"$PACK_UUID\" --argjson ver \"$PACK_VERSION\" \\\n              '. + [{\"pack_id\": $uuid, \"version\": $ver}]' /tmp/rp.json > /tmp/rp_new.json\n            mv /tmp/rp_new.json /tmp/rp.json\n          fi\n        done\n\n        # Activate packs for the world\n        mkdir -p \"$DATA_DIR/worlds/$LEVEL_NAME\"\n        cp /tmp/bp.json \"$DATA_DIR/worlds/$LEVEL_NAME/world_behavior_packs.json\"\n        cp /tmp/rp.json \"$DATA_DIR/worlds/$LEVEL_NAME/world_resource_packs.json\"\n\n        echo \"=== Installed behavior packs ===\"\n        cat \"$DATA_DIR/worlds/$LEVEL_NAME/world_behavior_packs.json\"\n        echo \"=== Installed resource packs ===\"\n        cat \"$DATA_DIR/worlds/$LEVEL_NAME/world_resource_packs.json\"\n\n        # Mark as installed\n        touch \"$DATA_DIR/.wither-storm-addon-v0.4.8.4\"\n        echo \"Wither Storm addon installation complete!\"\n    volumeMounts:\n      - name: datadir\n        mountPath: /data\nstartupProbe:\n  enabled: true\n  failureThreshold: 60\n  periodSeconds: 10\nlivenessProbe:\n  initialDelaySeconds: 60\nreadinessProbe:\n  initialDelaySeconds: 60\npersistence:\n  dataDir:\n    enabled: true\n    existingClaim: minecraft-witherstorm-data\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/minecraft-witherstorm/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: minecraft-witherstorm\n  namespace: game-servers\nspec:\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n  path: \"./apps/base/game-servers/minecraft-witherstorm/app\"\n  wait: true\n  targetNamespace: game-servers\n  sourceRef:\n    kind: ExternalArtifact\n    name: minecraft-witherstorm\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/game-servers/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: game-servers\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/harbor/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: harbor\nspec:\n  interval: 1h\n  chart:\n    spec:\n      chart: harbor\n      version: 1.19.0\n      sourceRef:\n        kind: HelmRepository\n        name: harbor-charts\n        namespace: flux-system\n      interval: 10m\n  values:\n    expose:\n      type: clusterIP\n      tls:\n        enabled: false\n    externalURL: https://harbor.${CLUSTER_DOMAIN}\n    persistence:\n      enabled: true\n      persistentVolumeClaim:\n        registry:\n          storageClass: ceph-block\n          size: 50Gi\n        database:\n          storageClass: ceph-block\n          size: 5Gi\n        redis:\n          storageClass: ceph-block\n          size: 1Gi\n        trivy:\n          storageClass: ceph-block\n          size: 5Gi\n    trivy:\n      enabled: true\n    metrics:\n      enabled: true\n      serviceMonitor:\n        enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/harbor/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: harbor\n  namespace: harbor\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'harbor.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: harbor-core\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/harbor/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/harbor/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: harbor-registry\nspec:\n  sourcePVC: harbor-registry\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: harbor-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: harbor-database\nspec:\n  sourcePVC: database-data-harbor-database-0\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 2Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: harbor-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/harbor/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: harbor-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: harbor-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/harbor/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: harbor\n  namespace: harbor\nspec:\n  path: \"./apps/base/harbor/harbor/app\"\n  wait: true\n  dependsOn:\n    - name: cert-manager\n      namespace: network-system\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: harbor\n  sourceRef:\n    kind: ExternalArtifact\n    name: harbor\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: harbor\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/harbor/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: harbor\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: autobrr\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: autobrr-secret\n    template:\n      data:\n        AUTOBRR__SESSION_SECRET: \"{{ .AUTOBRR_SESSION_SECRET }}\"\n  dataFrom:\n    - extract:\n        key: autobrr\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app autobrr\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  dependsOn:\n    - name: qbittorrent\n      namespace: home-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/autobrr/autobrr\n              tag: v1.79.0@sha256:5b8c29a86598907496af01ec75ef21f9c0e4e28ce9d6ae6496ef91c71543ec20\n            env:\n              AUTOBRR__HOST: 0.0.0.0\n              AUTOBRR__PORT: &port 80\n              AUTOBRR__METRICS_ENABLED: true\n              AUTOBRR__METRICS_HOST: 0.0.0.0\n              AUTOBRR__METRICS_PORT: &metricsPort 9094\n              AUTOBRR__CHECK_FOR_UPDATES: false\n              AUTOBRR__LOG_LEVEL: INFO\n            envFrom:\n              - secretRef:\n                  name: autobrr-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /api/healthz/liveness\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n                memory: 256Mi\n              limits:\n                memory: 512Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n          metrics:\n            port: *metricsPort\n    serviceMonitor:\n      app:\n        serviceName: autobrr\n        endpoints:\n          - port: metrics\n    persistence:\n      config:\n        existingClaim: autobrr-ceph\n      config-log:\n        type: emptyDir\n        globalMounts:\n          - path: /config/log\n      tmp:\n        type: emptyDir\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: autobrr\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'autobrr.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: autobrr\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: autobrr-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: autobrr\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: autobrr\nspec:\n  sourcePVC: autobrr-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: autobrr-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: autobrr-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: autobrr-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/autobrr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: &app autobrr\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/autobrr/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: autobrr\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: bazarr\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: bazarr-secret\n    template:\n      data:\n        BAZARR__AUTH__APIKEY: \"{{ .BAZARR_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: bazarr\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: bazarr\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      bazarr:\n        annotations:\n          reloader.stakater.com/auto: \"true\"\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/bazarr\n              tag: 1.5.6@sha256:79fc37491f55c7e24427bcd669bce3df2d7415ca432a47ce9d53cc5988af8411\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n            envFrom:\n              - secretRef:\n                  name: bazarr-secret\n            probes:\n              liveness:\n                enabled: true\n                spec:\n                  periodSeconds: 30\n                  timeoutSeconds: 5\n                  failureThreshold: 5\n              readiness:\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /api/system/ping\n                    port: &port 6767\n                  periodSeconds: 10\n                  timeoutSeconds: 5\n                  failureThreshold: 5\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 256Mi\n              limits:\n                memory: 2Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: bazarr\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: bazarr-ceph\n      tmp:\n        type: emptyDir\n      media:\n        type: nfs\n        server: ${CLUSTER_NFS_SERVER}\n        path: ${CLUSTER_NFS_PATH}\n        globalMounts:\n          - path: /media\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: bazarr\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'bazarr.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: bazarr\n          port: 6767\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: bazarr-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: bazarr\nspec:\n  sourcePVC: bazarr-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: bazarr-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: bazarr-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: bazarr-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/bazarr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: bazarr\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/bazarr/app\"\n  wait: false\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: bazarr\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app home-assistant\n  namespace: home-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/home-assistant\n              tag: 2026.5.1@sha256:516ae5c85089b3f2960cf2a21dc3c105356969499964fabf0b0358e5f3a7e0a2\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              HASS_HTTP_TRUSTED_PROXY_1: 192.168.50.0/24\n              HASS_HTTP_TRUSTED_PROXY_2: 192.168.86.0/24\n              HASS_HTTP_TRUSTED_PROXY_3: 10.0.0.0/8\n            # TODO: Setup local secrets\n            # envFrom:\n            #   - secretRef:\n            #       name: home-assistant-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8123\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                custom: true\n                spec:\n                  tcpSocket:\n                    port: 8123\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n                memory: 512Mi\n              limits:\n                memory: 2Gi\n          code-server:\n            image:\n              repository: ghcr.io/coder/code-server\n              tag: 4.118.0@sha256:4aff9947c113487113201da811564fade1af5f23038b4d683998d024eebbac92\n            args: [\"--auth\", \"none\", \"--user-data-dir\", \"/config/.vscode\", \"--extensions-dir\", \"/config/.vscode\", \"--port\", \"12321\", \"/config\"]\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 512Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: home-assistant\n        ports:\n          http:\n            port: 8123\n          code-server:\n            port: 12321\n    persistence:\n      config:\n        existingClaim: home-assistant-ceph\n        globalMounts:\n          - path: /config\n      logs:\n        type: emptyDir\n        globalMounts:\n          - path: /config/logs\n      tts:\n        type: emptyDir\n        globalMounts:\n          - path: /config/tts\n      tmp:\n        type: emptyDir\n        globalMounts:\n          - path: /tmp\n      venv:\n        type: emptyDir\n        globalMounts:\n          - path: /config/.venv\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: home-assistant\n  namespace: home-system\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'hass.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: home-assistant\n          port: 8123\n          weight: 100\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: home-assistant-code\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'hass-code.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: home-assistant\n          port: 12321\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: home-assistant-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/app/pvc.yaml",
    "content": "apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: home-assistant\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: home-assistant\nspec:\n  sourcePVC: home-assistant-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: home-assistant-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: home-assistant-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: home-assistant-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/home-assistant/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: home-assistant\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/home-assistant/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: home-assistant\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: jellyseerr\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: jellyseerr-secret\n    template:\n      data:\n        API_KEY: \"{{ .JELLYSEERR_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: jellyseerr\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app jellyseerr\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: docker.io/fallenbagel/jellyseerr\n              tag: 2.7.3@sha256:4538137bc5af902dece165f2bf73776d9cf4eafb6dd714670724af8f3eb77764\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              LOG_LEVEL: \"info\"\n              PORT: &port 80\n            envFrom:\n              - secretRef:\n                  name: jellyseerr-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /api/v1/status\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 5\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n                memory: 512Mi\n              limits:\n                memory: 2Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: jellyseerr-ceph\n        globalMounts:\n          - path: /app/config\n      cache:\n        existingClaim: jellyseerr-cache-ceph\n        globalMounts:\n          - path: /app/config/cache\n      logs:\n        type: emptyDir\n        globalMounts:\n          - path: /app/config/logs\n      tmp:\n        type: emptyDir\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: jellyseerr\n  namespace: home-system\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'requests.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: jellyseerr\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: jellyseerr-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: jellyseerr-cache-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: jellyseerr\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: jellyseerr-cache\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: jellyseerr\nspec:\n  sourcePVC: jellyseerr-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: jellyseerr-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: jellyseerr-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: jellyseerr-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/jellyseerr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: jellyseerr\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/jellyseerr/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: jellyseerr\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: home-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/mosquitto/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app mosquitto\n  namespace: home-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: public.ecr.aws/docker/library/eclipse-mosquitto\n              tag: 2.0.22\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 100Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        type: LoadBalancer\n        annotations:\n          lbipam.cilium.io/ips: '${CLUSTER_LB_MOSQUITTO}'\n        ports:\n          http:\n            port: 1883\n    configMaps:\n      config:\n        data:\n          mosquitto.conf: |\n            allow_anonymous true\n            autosave_interval 60\n            connection_messages false\n            listener 1883\n            per_listener_settings false\n            persistence true\n            persistence_location /data\n    persistence:\n      data:\n        existingClaim: mosquitto-cache-ceph\n      config-file:\n        type: configMap\n        name: mosquitto\n        advancedMounts:\n          mosquitto:\n            app:\n              - path: /mosquitto/config/mosquitto.conf\n                subPath: mosquitto.conf\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/mosquitto/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/mosquitto/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: mosquitto-cache-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 1Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/mosquitto/app/pvc.yaml",
    "content": "apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: mosquitto-cache\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 1Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/mosquitto/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: mosquitto\nspec:\n  sourcePVC: mosquitto-cache-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: mosquitto-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/mosquitto/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: mosquitto-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: mosquitto-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/mosquitto/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: mosquitto\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/mosquitto/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: mosquitto\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: home-system\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: prowlarr\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: prowlarr-secret\n    template:\n      data:\n        PROWLARR__AUTH__APIKEY: \"{{ .PROWLARR_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: prowlarr\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app prowlarr\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/prowlarr\n              tag: 2.3.7.5365@sha256:b9557d772c974901aed9285189d904b613f1f07750fca930eecfe78544bd3d48\n            env:\n              PROWLARR__APP__INSTANCENAME: Prowlarr\n              PROWLARR__APP__THEME: dark\n              PROWLARR__AUTH__METHOD: External\n              PROWLARR__AUTH__REQUIRED: DisabledForLocalAddresses\n              PROWLARR__LOG__DBENABLED: \"False\"\n              PROWLARR__LOG__LEVEL: info\n              PROWLARR__SERVER__PORT: &port 80\n              PROWLARR__UPDATE__BRANCH: develop\n              TZ: ${CLUSTER_TIMEZONE}\n            envFrom:\n              - secretRef:\n                  name: prowlarr-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /ping\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 1Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: prowlarr-ceph\n      tmp:\n        type: emptyDir\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: prowlarr\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'prowlarr.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: prowlarr\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: prowlarr-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: prowlarr\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: prowlarr\nspec:\n  sourcePVC: prowlarr-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: prowlarr-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: prowlarr-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: prowlarr-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/prowlarr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: prowlarr\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/prowlarr/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: prowlarr\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app qbittorrent\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/qbittorrent\n              tag: 5.2.0@sha256:788796013c3da75f2dba568c5319975a5c41f555586dfd13987be4631181e00e\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              QBT_WEBUI_PORT: &port 80\n              QBT_TORRENTING_PORT: &torrentPort 50413\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /api/v2/app/version\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 4Gi\n    defaultPodOptions:\n      terminationGracePeriodSeconds: 300\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        type: LoadBalancer\n        annotations:\n          lbipam.cilium.io/ips: ${CLUSTER_LB_QB}\n        ports:\n          http:\n            port: *port\n          bittorrent:\n            enabled: true\n            port: *torrentPort\n            protocol: TCP\n    persistence:\n      config:\n        existingClaim: qbittorrent-ceph\n      tmp:\n        type: emptyDir\n      media:\n        type: nfs\n        server: ${CLUSTER_NFS_SERVER}\n        path: ${CLUSTER_NFS_PATH}\n        globalMounts:\n          - path: /media/Downloads/qbittorrent\n            subPath: Downloads/qbittorrent\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: qbittorrent\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'qb.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: qbittorrent\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: home-system\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/values/persistence/scripts/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: qbittorrent-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: qbittorrent\n  namespace: home-system\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: qbittorrent\nspec:\n  sourcePVC: qbittorrent-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: qbittorrent-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: qbittorrent-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: qbittorrent-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qbittorrent/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: qbittorrent\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/qbittorrent/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: qbittorrent\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: qui\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: qui-secret\n    template:\n      data:\n        QUI__SESSION_SECRET: \"{{ .QUI_SESSION_SECRET }}\"\n  dataFrom:\n    - extract:\n        key: qui\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app qui\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/autobrr/qui\n              tag: v1.18.0\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              QUI__HOST: 0.0.0.0\n              QUI__PORT: &port 80\n            envFrom:\n              - secretRef:\n                  name: \"{{ .Release.Name }}-secret\"\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /health\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 512Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: \"{{ .Release.Name }}\"\n      media:\n        type: nfs\n        server: ${CLUSTER_NFS_SERVER}\n        path: ${CLUSTER_NFS_PATH}\n        globalMounts:\n          - path: /media\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: qui\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'qui.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: qui\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: home-system\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/values/persistence/scripts/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: qui\n  namespace: home-system\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 2Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: qui\nspec:\n  sourcePVC: qui\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: qui-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: qui-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: qui-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/qui/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: qui\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/qui/app\"\n  wait: false\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: qui\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: radarr\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: radarr-secret\n    template:\n      data:\n        RADARR__AUTH__APIKEY: \"{{ .RADARR_API_KEY  }}\"\n  dataFrom:\n    - extract:\n        key: radarr\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: radarr\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      radarr:\n        annotations:\n          reloader.stakater.com/auto: \"true\"\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/radarr\n              tag: 6.2.0.10390@sha256:be596a2f896fdf15077af027f44500f73e1f6fb7b450a6494b37dd25b7cc5927\n            env:\n              RADARR__APP__INSTANCENAME: Radarr\n              RADARR__APP__THEME: dark\n              RADARR__AUTH__METHOD: External\n              RADARR__AUTH__REQUIRED: DisabledForLocalAddresses\n              RADARR__LOG__DBENABLED: \"False\"\n              RADARR__LOG__LEVEL: info\n              RADARR__SERVER__PORT: &port 80\n              RADARR__UPDATE__BRANCH: develop\n              TZ: ${CLUSTER_TIMEZONE}\n            envFrom:\n              - secretRef:\n                  name: radarr-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /ping\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 4Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: radarr\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: radarr-ceph\n      tmp:\n        type: emptyDir\n      media:\n        type: nfs\n        server: ${CLUSTER_NFS_SERVER}\n        path: ${CLUSTER_NFS_PATH}\n        globalMounts:\n          - path: /media\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: radarr\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'radarr.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: radarr\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: radarr-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: radarr\n  namespace: home-system\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: radarr\nspec:\n  sourcePVC: radarr-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: radarr-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: radarr-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: radarr-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/radarr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: radarr\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/radarr/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: radarr\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: recyclarr\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: recyclarr-secret\n    template:\n      data:\n        RADARR_API_KEY: \"{{ .RADARR_API_KEY }}\"\n        SONARR_API_KEY: \"{{ .SONARR_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: radarr\n    - extract:\n        key: sonarr\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app recyclarr\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        type: cronjob\n        cronjob:\n          schedule: 0 0 * * *\n          backoffLimit: 0\n          concurrencyPolicy: Forbid\n          successfulJobsHistory: 1\n          failedJobsHistory: 1\n          ttlSecondsAfterFinished: 86400\n        containers:\n          app:\n            image:\n              repository: ghcr.io/recyclarr/recyclarr\n              tag: 8.6.0@sha256:3c38ceeb54438dd8327e4e65c9b48ba601a6d20fff833342d93c9b0bc4b1930b\n            env:\n              RECYCLARR_DATA_DIR: /tmp\n            envFrom:\n              - secretRef:\n                  name: recyclarr-secret\n            args: [\"sync\"]\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 128Mi\n        pod:\n          restartPolicy: Never\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    persistence:\n      config:\n        existingClaim: recyclarr-ceph\n      config-file:\n        type: configMap\n        name: recyclarr-configmap\n        globalMounts:\n          - path: /config/recyclarr.yml\n            subPath: recyclarr.yml\n            readOnly: true\n      tmpfs:\n        type: emptyDir\n        advancedMounts:\n          recyclarr:\n            app:\n              - path: /config/logs\n                subPath: logs\n              - path: /config/repositories\n                subPath: repositories\n              - path: /tmp\n                subPath: tmp\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n\nconfigMapGenerator:\n  - name: recyclarr-configmap\n    files:\n      - recyclarr.yml=./resources/recyclarr.yml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/values/persistence/config-file/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: recyclarr-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: recyclarr\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: recyclarr\nspec:\n  sourcePVC: recyclarr-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: recyclarr-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/resources/recyclarr.yml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/recyclarr/recyclarr/refs/tags/v8.0.0/schemas/config-schema.json\nsonarr:\n  series:\n    base_url: http://sonarr.home-system.svc.cluster.local\n    api_key: !env_var SONARR_API_KEY\n    delete_old_custom_formats: true\n    media_management:\n      propers_and_repacks: do_not_prefer\n    quality_definition:\n      type: series\n    quality_profiles:\n      - trash_id: 72dae194fc92bf828f32cde7744e51a1 # WEB-1080p\n        reset_unmatched_scores:\n          enabled: true\n    custom_formats:\n      - trash_ids:\n          - 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups\n          - 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup\n          - e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated\n          - 06d66ab109d4d2eddb2794d21526d140 # Retags\n          - 1b3994c551cbb92a2c781af061f4ab44 # Scene\n        assign_scores_to:\n          - name: WEB-1080p\n\nradarr:\n  movies:\n    base_url: http://radarr.home-system.svc.cluster.local\n    api_key: !env_var RADARR_API_KEY\n    delete_old_custom_formats: true\n    media_management:\n      propers_and_repacks: do_not_prefer\n    quality_definition:\n      type: movie\n    quality_profiles:\n      - trash_id: d1d67249d3890e49bc12e275d989a7e9 # HD Bluray + WEB\n        reset_unmatched_scores:\n          enabled: true\n    custom_formats:\n      - trash_ids:\n          - b6832f586342ef70d9c128d40c07b872 # Bad Dual Groups\n          - ae9b7c9ebde1f3bd336a8cbd1ec4c5e5 # No-RlsGroup\n          - 7357cf5161efbf8c4d5d0c30b4815ee2 # Obfuscated\n          - 5c44f52a8714fdd79bb4d98e2673be1f # Retags\n          - f537cf427b64c38c8e36298f657e4828 # Scene\n        assign_scores_to:\n          - name: HD Bluray + WEB\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: recyclarr-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: recyclarr-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/recyclarr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: recyclarr\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/recyclarr/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: recyclarr\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: sabnzbd\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: sabnzbd-secret\n    template:\n      data:\n        CROSS_SEED_API_KEY: \"{{ .CROSS_SEED_API_KEY }}\"\n        SABNZBD__API_KEY: \"{{ .SABNZBD_API_KEY }}\"\n        SABNZBD__NZB_KEY: \"{{ .SABNZBD_NZB_KEY }}\"\n  dataFrom:\n    - extract:\n        key: sabnzbd\n    - extract:\n        key: cross-seed\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app sabnzbd\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/sabnzbd\n              tag: 5.0.3@sha256:53064020792b2e21305c892c11aaa1eb32af2141cbd59119b52df226d664cd05\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              SABNZBD__PORT: &port 80\n              SABNZBD__HOST_WHITELIST_ENTRIES: >-\n                sabnzbd, sabnzbd.home-system, sabnzbd.home-system.svc, sabnzbd.home-system.svc.cluster, sabnzbd.home-system.svc.cluster.local, sab.${CLUSTER_DOMAIN}\n              XSEED_HOST: cross-seed.home-system.svc.cluster.local\n              XSEED_PORT: 80\n              XSEED_APIKEY:\n                valueFrom:\n                  secretKeyRef:\n                    name: sabnzbd-secret\n                    key: CROSS_SEED_API_KEY\n            envFrom:\n              - secretRef:\n                  name: sabnzbd-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /api?mode=version\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 4Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: sabnzbd-ceph\n        advancedMounts:\n          sabnzbd:\n            app:\n              - path: /config\n      tmpfs:\n        type: emptyDir\n        advancedMounts:\n          sabnzbd:\n            app:\n              - path: /config/logs\n                subPath: logs\n              - path: /tmp\n                subPath: tmp\n      scripts:\n        type: configMap\n        name: sabnzbd-scripts\n        defaultMode: 0775\n        advancedMounts:\n          sabnzbd:\n            app:\n              - path: /config/scripts\n      media:\n        type: nfs\n        server: ${CLUSTER_NFS_SERVER}\n        path: ${CLUSTER_NFS_PATH}\n        globalMounts:\n          - path: /media/Downloads/sabnzbd\n            subPath: Downloads/sabnzbd\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: sabnzbd\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'sab.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: sabnzbd\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n\nconfigMapGenerator:\n  - name: sabnzbd-scripts\n    files:\n      - resources/xseed.sh\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/values/persistence/scripts/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: sabnzbd-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: sabnzbd\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: sabnzbd\nspec:\n  sourcePVC: sabnzbd-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: sabnzbd-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/resources/xseed.sh",
    "content": "#!/usr/bin/env bash\n\nXSEED_HOST=${XSEED_HOST:-crossseed}\nXSEED_PORT=${XSEED_PORT:-8080}\nXSEED_APIKEY=${XSEED_APIKEY:-unset}\nXSEED_SLEEP_INTERVAL=${CROSS_SEED_SLEEP_INTERVAL:-30}\n\nSEARCH_PATH=$1\n\nresponse=$(curl \\\n  --silent \\\n  --output /dev/null \\\n  --write-out \"%{http_code}\" \\\n  --request POST \\\n  --data-urlencode \"path=${SEARCH_PATH}\" \\\n  --header \"X-Api-Key: ${XSEED_APIKEY}\" \\\n  \"http://${XSEED_HOST}:${XSEED_PORT}/api/webhook\"\n)\n\nif [[ \"${response}\" != \"204\" ]]; then\n  printf \"Failed to search cross-seed for '%s'\\n\" \"${SEARCH_PATH}\"\n  exit 1\nfi\n\nprintf \"Successfully searched cross-seed for '%s'\\n\" \"${SEARCH_PATH}\"\n\nsleep \"${XSEED_SLEEP_INTERVAL}\"\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: sabnzbd-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: sabnzbd-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sabnzbd/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: sabnzbd\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/sabnzbd/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: sabnzbd\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/smtp-relay/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: smtp-relay\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: smtp-relay-secret\n    template:\n      data:\n        SMTP_RELAY_HOSTNAME: \"{{ .SMTP_RELAY_HOSTNAME }}\"\n        SMTP_RELAY_PASSWORD: \"{{ .SMTP_RELAY_PASSWORD }}\"\n        SMTP_RELAY_SERVER: \"{{ .SMTP_RELAY_SERVER }}\"\n        SMTP_RELAY_USERNAME: \"{{ .SMTP_RELAY_USERNAME }}\"\n  dataFrom:\n    - extract:\n        key: smtp-relay\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/smtp-relay/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: smtp-relay\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      smtp-relay:\n        replicas: 2\n        strategy: RollingUpdate\n        annotations:\n          reloader.stakater.com/auto: \"true\"\n        containers:\n          app:\n            image:\n              repository: ghcr.io/foxcpp/maddy\n              tag: 0.9.4@sha256:cf79fddee12228b3c47af5fbbfadceef115d46d4ae434429bef70f1d565a0abf\n            env:\n              SMTP_RELAY_SMTP_PORT: &port 25\n            envFrom:\n              - secretRef:\n                  name: smtp-relay-secret\n            probes:\n              liveness:\n                enabled: true\n              readiness:\n                enabled: true\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n                memory: 32Mi\n              limits:\n                memory: 64Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: smtp-relay\n        ports:\n          smtp:\n            port: *port\n    configMaps:\n      config:\n        data:\n          maddy.conf: |-\n            state_dir /cache/state\n            runtime_dir /cache/run\n            tls off\n            hostname {env:SMTP_RELAY_HOSTNAME}\n            smtp tcp://0.0.0.0:{env:SMTP_RELAY_SMTP_PORT} {\n                default_source {\n                    deliver_to &remote_queue\n                }\n            }\n            target.queue remote_queue {\n                target &remote_smtp\n            }\n            target.smtp remote_smtp {\n                starttls yes\n                auth plain {env:SMTP_RELAY_USERNAME} {env:SMTP_RELAY_PASSWORD}\n                targets tcp://{env:SMTP_RELAY_SERVER}:587\n            }\n    persistence:\n      cache:\n        type: emptyDir\n      config-file:\n        type: configMap\n        identifier: config\n        globalMounts:\n          - path: /data/maddy.conf\n            subPath: maddy.conf\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/smtp-relay/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/smtp-relay/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: smtp-relay\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/smtp-relay/app\"\n  wait: true\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: smtp-relay\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: sonarr\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: sonarr-secret\n    template:\n      data:\n        SONARR__AUTH__APIKEY: \"{{ .SONARR_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: sonarr\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: sonarr\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      sonarr:\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/sonarr\n              tag: 4.0.17.2967@sha256:4ff5667a371e08b098858fa2457a99a5fef5f6a32640eb8567efe979d13ac9fc\n            env:\n              SONARR__APP__INSTANCENAME: Sonarr\n              SONARR__APP__THEME: dark\n              SONARR__AUTH__METHOD: External\n              SONARR__AUTH__REQUIRED: DisabledForLocalAddresses\n              SONARR__LOG__DBENABLED: \"False\"\n              SONARR__LOG__LEVEL: info\n              SONARR__SERVER__PORT: &port 80\n              SONARR__UPDATE__BRANCH: develop\n              TZ: ${CLUSTER_TIMEZONE}\n            envFrom:\n              - secretRef:\n                  name: sonarr-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /ping\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 100m\n                memory: 512Mi\n              limits:\n                memory: 4Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: sonarr\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: sonarr-ceph\n      tmp:\n        type: emptyDir\n      media:\n        type: nfs\n        server: ${CLUSTER_NFS_SERVER}\n        path: ${CLUSTER_NFS_PATH}\n        globalMounts:\n          - path: /media\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: sonarr\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'sonarr.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: sonarr\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: sonarr-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: sonarr\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: sonarr\nspec:\n  sourcePVC: sonarr-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: sonarr-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: sonarr-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: sonarr-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/sonarr/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: sonarr\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/sonarr/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: sonarr\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: tautulli\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: tautulli-secret\n    template:\n      data:\n        TAUTULLI_API_KEY: \"{{ .TAUTULLI_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: tautulli\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app tautulli\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        containers:\n          app:\n            image:\n              repository: ghcr.io/home-operations/tautulli\n              tag: 2.17.1@sha256:2183820d45a1413b4b8868fc18ad5eb9259630ea0151348cdc9cfb4017a0dd33\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              TAUTULLI_HTTP_BASE_URL: https://tautulli.${CLUSTER_DOMAIN}\n              TAUTULLI_HTTP_PORT: &port 80\n            envFrom:\n              - secretRef:\n                  name: tautulli-secret\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /status\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 1Gi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        fsGroup: 1000\n        fsGroupChangePolicy: OnRootMismatch\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    persistence:\n      config:\n        existingClaim: tautulli-ceph\n      tmpfs:\n        type: emptyDir\n        advancedMounts:\n          tautulli:\n            app:\n              - path: /config/logs\n                subPath: logs\n              - path: /tmp\n                subPath: tmp\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: tautulli\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'tautulli.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: tautulli\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: tautulli-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: tautulli\nspec:\n  accessModes: [\"ReadWriteOnce\"]\n  resources:\n    requests:\n      storage: 5Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: tautulli\nspec:\n  sourcePVC: tautulli-ceph\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: tautulli-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: tautulli-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: tautulli-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/tautulli/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: tautulli\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/tautulli/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: tautulli\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app zigbee2mqtt\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        type: deployment\n        replicas: 1\n        containers:\n          main:\n            image:\n              repository: ghcr.io/koenkk/zigbee2mqtt\n              tag: 2.10.0@sha256:e9279e580bb25c512cf6e54c36e215a5cbd2881d1f201cf2a8213a97b14be3d2\n            env:\n              TZ: ${CLUSTER_TIMEZONE}\n              ZIGBEE2MQTT_DATA: /data\n              ZIGBEE2MQTT_CONFIG_EXPERIMENTAL_NEW_API: true\n              # adapter\n              ZIGBEE2MQTT_CONFIG_SERIAL_PORT: tcp://${EXT_ZIGBEE_CONTROLLER_IP}:6638\n              ZIGBEE2MQTT_CONFIG_SERIAL_ADAPTER: zstack\n              ZIGBEE2MQTT_CONFIG_SERIAL_BAUDRATE: 115200\n              ZIGBEE2MQTT_CONFIG_ADVANCED_TRANSMIT_POWER: 20\n              ZIGBEE2MQTT_CONFIG_ADVANCED_DISABLE_LED: false\n              # mqtt\n              ZIGBEE2MQTT_CONFIG_MQTT_SERVER: \"mqtt://mosquitto.home-system.svc.cluster.local:1883\"\n              ZIGBEE2MQTT_CONFIG_MQTT_BASE_TOPIC: zigbee2mqtt\n              ZIGBEE2MQTT_CONFIG_MQTT_INCLUDE_DEVICE_INFORMATION: true\n              ZIGBEE2MQTT_CONFIG_MQTT_USER: ${MQTT_USER_USERNAME}\n              ZIGBEE2MQTT_CONFIG_MQTT_PASSWORD: ${MQTT_USER_PASSWORD}\n              ZIGBEE2MQTT_CONFIG_MQTT_VERSION: 5\n              ZIGBEE2MQTT_CONFIG_ADVANCED_LAST_SEEN: ISO_8601\n              # zigbee network\n              ZIGBEE2MQTT_CONFIG_ADVANCED_CHANNEL: 25\n              # frontend\n              ZIGBEE2MQTT_CONFIG_FRONTEND_ENABLED: true\n              ZIGBEE2MQTT_CONFIG_FRONTEND_PORT: &port 80\n              ZIGBEE2MQTT_CONFIG_FRONTEND_URL: https://zigbee2mqtt.${CLUSTER_DOMAIN}\n              # devices and groups\n              ZIGBEE2MQTT_CONFIG_DEVICES: devices.yaml\n              ZIGBEE2MQTT_CONFIG_GROUPS: groups.yaml\n              # logging\n              ZIGBEE2MQTT_CONFIG_ADVANCED_LOG_LEVEL: info\n              ZIGBEE2MQTT_CONFIG_ADVANCED_LOG_OUTPUT: '[\"console\"]'\n              # device-availability\n              ZIGBEE2MQTT_CONFIG_AVAILABILITY_ENABLED: true\n              ZIGBEE2MQTT_CONFIG_AVAILABILITY_ACTIVE_TIMEOUT: 60\n              ZIGBEE2MQTT_CONFIG_AVAILABILITY_PASSIVE_TIMEOUT: 2000\n              ZIGBEE2MQTT_CONFIG_DEVICE_OPTIONS_RETAIN: true\n              # home-assistant\n              ZIGBEE2MQTT_CONFIG_HOMEASSISTANT_ENABLED: true\n              ZIGBEE2MQTT_CONFIG_HOMEASSISTANT_DISCOVERY_TOPIC: homeassistant\n              ZIGBEE2MQTT_CONFIG_HOMEASSISTANT_STATUS_TOPIC: homeassistant/status\n              # security\n              ZIGBEE2MQTT_CONFIG_PERMIT_JOIN: true\n            probes:\n              liveness:\n                enabled: true\n              readiness:\n                enabled: true\n              startup:\n                enabled: true\n                spec:\n                  failureThreshold: 30\n                  periodSeconds: 10\n                  initialDelaySeconds: 10\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities:\n                drop: [\"ALL\"]\n            resources:\n              requests:\n                cpu: \"10m\"\n                memory: \"128Mi\"\n              limits:\n                memory: \"256Mi\"\n    service:\n      zigbee2mqtt:\n        controller: *app\n        ports:\n          http:\n            port: *port\n            protocol: HTTP\n            appProtocol: http\n    serviceMonitor:\n      app:\n        serviceName: *app\n        endpoints:\n          - port: http\n            scheme: http\n            path: /metrics\n            interval: 1m\n            scrapeTimeout: 10s\n    persistence:\n      data:\n        existingClaim: zigbee2mqtt-cache\n    defaultPodOptions:\n      automountServiceAccountToken: false\n      enableServiceLinks: false\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: &uid 1000\n        runAsGroup: *uid\n        fsGroup: *uid\n        fsGroupChangePolicy: Always\n        seccompProfile: { type: \"RuntimeDefault\" }\n      topologySpreadConstraints:\n        - maxSkew: 1\n          topologyKey: kubernetes.io/hostname\n          whenUnsatisfiable: DoNotSchedule\n          labelSelector:\n            matchLabels:\n              app.kubernetes.io/name: *app\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: zigbee2mqtt\n  namespace: home-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'zigbee2mqtt.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: zigbee2mqtt\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - pvc.yaml\n  - pvc-ceph.yaml\n  - replicationsource.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/app/pvc-ceph.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: zigbee2mqtt-cache-ceph\n  namespace: home-system\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 1Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/app/pvc.yaml",
    "content": "apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: zigbee2mqtt-cache\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 1Gi\n  storageClassName: truenas-iscsi-csi\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/app/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: zigbee2mqtt\nspec:\n  sourcePVC: zigbee2mqtt-cache\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: zigbee2mqtt-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/app/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: zigbee2mqtt-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: zigbee2mqtt-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/home-system/zigbee2mqtt/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: zigbee2mqtt\n  namespace: home-system\nspec:\n  path: \"./apps/base/home-system/zigbee2mqtt/app\"\n  wait: false\n  dependsOn:\n    - name: democratic-csi\n      namespace: democratic-csi\n    - name: mosquitto\n      namespace: home-system\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: home-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: zigbee2mqtt\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/auditnetworkpolicy-baseline.yaml",
    "content": "---\n# Cluster-wide audit-only default-deny baseline.\n#\n# Tells the kguardian-evaluator to evaluate every pod-to-pod flow in\n# the cluster against a \"deny everything ingress\" rule, *without\n# enforcing it*. Result: the Audit panel in the frontend (and the\n# audit_verdicts table in the broker) populate with a per-flow row\n# tagged \"WouldDeny\", giving you a complete picture of what cluster\n# traffic looks like before you commit to enforcement.\n#\n# kguardian itself is excluded so the evaluator + broker + frontend\n# don't drown out the signal with their own internal traffic.\n#\n# Promote per-namespace by copying the spec under kind: NetworkPolicy\n# (or use Calico GlobalNetworkPolicy / k8s AdminNetworkPolicy if your\n# CNI supports cluster-wide enforcement). See the chart's\n# UPGRADING.md / docs/concepts/audit-network-policy.mdx.\napiVersion: kguardian.dev/v1alpha1\nkind: AuditClusterNetworkPolicy\nmetadata:\n  name: cluster-baseline-audit\nspec:\n  # Empty namespaceSelector with an explicit not-in match excludes\n  # kguardian's own namespace. Everywhere else gets evaluated.\n  namespaceSelector:\n    matchExpressions:\n      - key: kubernetes.io/metadata.name\n        operator: NotIn\n        values: [kguardian, kube-system, flux-system]\n  podSelector: {}\n  policyTypes: [Ingress]\n  # No ingress rules → default-deny in every matched namespace.\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app kguardian\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kguardian\n  valuesFrom:\n    - kind: ConfigMap\n      name: kguardian-values\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: kguardian\n  namespace: kguardian\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'kguardian.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: kguardian-frontend\n          port: 5173\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n  - ocirepository.yaml\n  - pvc-database.yaml\n  - auditnetworkpolicy-baseline.yaml\n\nconfigMapGenerator:\n  - name: kguardian-values\n    namespace: kguardian\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kguardian\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.11.1\n  url: oci://ghcr.io/kguardian-dev/charts/kguardian\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/pvc-database.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: kguardian-db\n  namespace: kguardian\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 10Gi\n  storageClassName: ceph-block\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/app/values.yaml",
    "content": "---\ncontroller:\n  image:\n    # v1.8.2 — eBPF ring-buffer callbacks log first receiver-closed once\n    # then drop subsequent events silently, instead of flooding stderr at\n    # syscall frequency (kguardian-dev/kguardian#880).\n    tag: \"v1.8.2\"\n    sha: \"sha256:bfb9a3b52bc6a146acf19ebec700343ae245431fb17555e8a55ed239caa37356\"\n  excludedNamespaces:\n    - kguardian\n\nbroker:\n  image:\n    # v1.9.1 — /health checks schema state so kubelet self-heals on DB wipe\n    # (kguardian-dev/kguardian#876). Validated end-to-end against this cluster.\n    tag: \"v1.9.1\"\n    sha: \"sha256:65261cdfa672c7ad61044e4fe58d945cc5b422dd64de6341aa23c46fd555570e\"\n  resources:\n    limits:\n      memory: 2Gi\n    requests:\n      cpu: 500m\n      memory: 512Mi\n\nfrontend:\n  image:\n    tag: \"v1.9.0\"\n    sha: \"sha256:32bb6300f51f0bdc3040d6bfa524c8ad56ecd27feb76fb28f9e46dcda7eede83\"\n\nllmBridge:\n  enabled: true\n  image:\n    tag: \"v1.2.3\"\n    sha: \"sha256:333aa8e252dcea145975d094408a7ab1e4abaedd5ac39e617bdf1cc5894a8437\"\n  secrets:\n    openai:\n      enabled: true\n      name: \"kguardian-secrets\"\n\n# kguardian-evaluator — audit-mode policy preview (chart 1.11.0+).\n# Watches AuditNetworkPolicy / AuditClusterNetworkPolicy CRDs and reports\n# flows that *would* be denied (and that are explicitly allowed) without\n# blocking traffic. Surfaces in the frontend's \"Audit\" panel.\nevaluator:\n  image:\n    # v0.2.2 — empty results encode as `[]` not `null`, eliminating\n    # broker decode warnings on flows with no matching policies\n    # (kguardian-dev/kguardian#880).\n    tag: \"v0.2.2\"\n    sha: \"sha256:a7c21bdb710402059df9a2709ec64b607be63de9337e47967b0bf97af3948fe4\"\n\ndatabase:\n  # Pin postgres image — `latest` drifts and PG major-version bumps break the on-disk format\n  image:\n    tag: \"18.1\"\n    sha: \"sha256:1090bc3a8ccfb0b55f78a494d76f8d603434f7e4553543d6e807bc7bd6bbd17f\"\n  # Persistent storage so the DB survives pod restarts (chart default is emptyDir → wipes on every recreate)\n  persistence:\n    enabled: true\n    existingClaim: kguardian-db\n  # Sized to observed load: postgres uses 2.0–2.8 cores under autovacuum + ingest pressure\n  resources:\n    limits:\n      memory: 1Gi\n    requests:\n      cpu: \"2\"\n      memory: 512Mi\n\nmcpServer:\n  enabled: false\n  useKmcp: false\n  image:\n    tag: \"v1.3.2\"\n    sha: \"sha256:1ca186593b1948ec5a237f8f863047bea56880d73015b35576ec45a27b51a604\"\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kguardian/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kguardian\n  namespace: kguardian\nspec:\n  path: \"./apps/base/kguardian/kguardian/app\"\n  wait: true\n  targetNamespace: kguardian\n  sourceRef:\n    kind: ExternalArtifact\n    name: kguardian\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: kguardian\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kguardian/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: kguardian\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: cilium\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  configMapRef:\n    name: cilium-dashboard\n    key: cilium-dashboard.json\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: cilium-operator\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  configMapRef:\n    name: cilium-operator-dashboard\n    key: cilium-operator-dashboard.json\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: cilium\n  namespace: kube-system\nspec:\n  interval: 5m\n  timeout: 10m\n  chartRef:\n    kind: OCIRepository\n    name: cilium\n  valuesFrom:\n    - kind: ConfigMap\n      name: cilium-values\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: hubble-ui\n  namespace: network-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'hubble.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: hubble-ui\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: kube-system\n\nresources:\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - loadbalancer.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: cilium-values\n    files:\n      - values.yaml=./values.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/valuesFrom/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/loadbalancer.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cilium.io/ciliuml2announcementpolicy_v2alpha1.json\napiVersion: cilium.io/v2alpha1\nkind: CiliumL2AnnouncementPolicy\nmetadata:\n  name: l2-policy\nspec:\n  nodeSelector:\n    matchLabels:\n      kubernetes.io/os: linux\n  externalIPs: true\n  loadBalancerIPs: true\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cilium.io/ciliumloadbalancerippool_v2alpha1.json\napiVersion: cilium.io/v2alpha1\nkind: CiliumLoadBalancerIPPool\nmetadata:\n  name: l2-pool\nspec:\n  allowFirstLastIPs: \"Yes\"\n  blocks:\n    - start: 192.168.50.180\n      stop: 192.168.50.199\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: cilium\n  namespace: kube-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.19.4\n  url: oci://quay.io/cilium/charts/cilium\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/app/values.yaml",
    "content": "---\nannotateK8sNode: true\nautoDirectNodeRoutes: true\nbandwidthManager:\n  bbr: true\n  enabled: true\nbpf:\n  datapathMode: netkit\n  masquerade: true\n  preallocateMaps: true\nbpfClockProbe: true\nbgpControlPlane:\n  enabled: false\ncgroup:\n  autoMount:\n    enabled: false\n  hostRoot: /sys/fs/cgroup\ncni:\n  exclusive: false\ndashboards:\n  enabled: true\n  annotations:\n    grafana_folder: kube-system\nenableIPv4BIGTCP: true\nendpointRoutes:\n  enabled: true\nenvoy:\n  enabled: false\nhubble:\n  enabled: true\n  metrics:\n    enabled:\n      - dns:query;ignoreAAAA\n      - drop\n      - tcp\n      - flow\n      - icmp\n      - http\n      - port-distribution\n      - policy-verdict:sourceContext=pod;destinationContext=pod;labelsContext=source_namespace,destination_namespace\n    enableOpenMetrics: true\n    serviceMonitor:\n      enabled: true\n      labels:\n        prometheus: kube-prometheus\n  ui:\n    enabled: true\n    PodDisruptionBudget:\n      enabled: true\n      minAvailable: 1\n      unhealthyPodEvictionPolicy: AlwaysAllow\n  relay:\n    enabled: true\n    PodDisruptionBudget:\n      enabled: true\n      minAvailable: 1\n      unhealthyPodEvictionPolicy: AlwaysAllow\nipam:\n  mode: kubernetes\nipv4NativeRoutingCIDR: 10.244.0.0/16\nk8sServiceHost: 127.0.0.1\nk8sServicePort: 7445\nkubeProxyReplacement: true\nkubeProxyReplacementHealthzBindAddr: 0.0.0.0:10256\nl2announcements:\n  enabled: true\nloadBalancer:\n  algorithm: maglev\n  mode: hybrid\n  serviceTopology: true\nlocalRedirectPolicies:\n  enabled: true\noperator:\n  priorityClassName: system-cluster-critical\n  PodDisruptionBudget:\n    enabled: true\n    minAvailable: 1\n    unhealthyPodEvictionPolicy: AlwaysAllow\n  dashboards:\n    enabled: true\n    annotations:\n      grafana_folder: kube-system\n  prometheus:\n    enabled: true\n    serviceMonitor:\n      enabled: true\n      trustCRDsExist: true\n  replicas: 2\n  rollOutPods: true\npmtuDiscovery:\n  enabled: true\nprometheus:\n  enabled: true\n  serviceMonitor:\n    enabled: true\n    trustCRDsExist: true\npriorityClassName: system-node-critical\nrollOutCiliumPods: true\nroutingMode: native\nsecurityContext:\n  capabilities:\n    ciliumAgent:\n      - CHOWN\n      - KILL\n      - NET_ADMIN\n      - NET_RAW\n      - IPC_LOCK\n      - SYS_ADMIN\n      - SYS_RESOURCE\n      - PERFMON\n      - BPF\n      - DAC_OVERRIDE\n      - FOWNER\n      - SETGID\n      - SETUID\n    cleanCiliumState:\n      - NET_ADMIN\n      - SYS_ADMIN\n      - SYS_RESOURCE\nsocketLB:\n  enabled: true\n  hostNamespaceOnly: true\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/cilium/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cilium\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/cilium/app\"\n  wait: false\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: cilium\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/descheduler/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: descheduler\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: descheduler\n  valuesFrom:\n    - kind: ConfigMap\n      name: descheduler-values\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/descheduler/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: descheduler-values\n    namespace: kube-system\n    files:\n      - values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/descheduler/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/valuesFrom/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/descheduler/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: descheduler\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.35.1\n  url: oci://ghcr.io/home-operations/charts-mirror/descheduler\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/descheduler/app/values.yaml",
    "content": "service:\n  enabled: true\nserviceMonitor:\n  enabled: true\nkind: Deployment\nleaderElection:\n  enabled: true\n  leaseDuration: 30s\n  renewDeadline: 15s\n  retryPeriod: 5s\n  resourceLock: \"leases\"\n  resourceName: \"descheduler\"\n  resourceNamescape: \"kube-system\"\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/descheduler/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: descheduler\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/descheduler/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: descheduler\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/keda/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: keda\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: keda\n  values:\n    crds:\n      install: true\n    operator:\n      replicaCount: 2\n    metricsServer:\n      replicaCount: 2\n    prometheus:\n      metricServer:\n        enabled: true\n        serviceMonitor:\n          enabled: true\n      operator:\n        enabled: true\n        serviceMonitor:\n          enabled: true\n      webhooks:\n        enabled: true\n        serviceMonitor:\n          enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/keda/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/keda/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: keda\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 2.19.0\n  url: oci://ghcr.io/home-operations/charts-mirror/keda\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/keda/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: keda\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/keda/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: keda\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/kubelet-csr-approver/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: kubelet-csr-approver\n  valuesFrom:\n    - kind: ConfigMap\n      name: kubelet-csr-approver-values\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/kubelet-csr-approver/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: kubelet-csr-approver-values\n    namespace: kube-system\n    files:\n      - values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/kubelet-csr-approver/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/valuesFrom/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/kubelet-csr-approver/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.2.13\n  url: oci://ghcr.io/postfinance/charts/kubelet-csr-approver\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/kubelet-csr-approver/app/values.yaml",
    "content": "metrics:\n  enable: true\n  serviceMonitor:\n    enabled: true\nproviderRegex: ^talos-\\d$\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/kubelet-csr-approver/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/kubelet-csr-approver/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kubelet-csr-approver\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: kube-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n  - priorityclass.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/metrics-server/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: metrics-server\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: metrics-server\n  values:\n    args:\n      - --kubelet-insecure-tls\n      - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n      - --kubelet-use-node-status-port\n      - --metric-resolution=15s\n    metrics:\n      enabled: true\n    serviceMonitor:\n      enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/metrics-server/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/metrics-server/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: metrics-server\n  namespace: kube-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 3.13.0\n  url: oci://ghcr.io/home-operations/charts-mirror/metrics-server\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/metrics-server/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: metrics-server\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/metrics-server/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: metrics-server\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: kube-system\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/priorityclass.yaml",
    "content": "---\napiVersion: scheduling.k8s.io/v1\ndescription: Used for cluster critical pods that must not be moved from their current node.\nkind: PriorityClass\nmetadata:\n  name: platform-cluster-critical\npreemptionPolicy: PreemptLowerPriority\nvalue: 100000000\n---\napiVersion: scheduling.k8s.io/v1\ndescription: Used for cluster critical pods that must not be moved from their current node.\nkind: PriorityClass\nmetadata:\n  name: platform-node-critical\npreemptionPolicy: PreemptLowerPriority\nvalue: 100001000\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/reflector/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app reflector\n  namespace: kube-system\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: reflector\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/reflector/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/reflector/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: reflector\n  namespace: kube-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 10.0.43\n  url: oci://ghcr.io/emberstack/helm-charts/reflector\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/reflector/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: reflector\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/reflector/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: reflector\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/snapshot-controller/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: snapshot-controller\n  namespace: kube-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: snapshot-controller\n  values:\n    controller:\n      serviceMonitor:\n        create: true\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/snapshot-controller/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/snapshot-controller/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: snapshot-controller\n  namespace: kube-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 5.0.4\n  url: oci://ghcr.io/piraeusdatastore/helm-charts/snapshot-controller\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/snapshot-controller/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: snapshot-controller\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/snapshot-controller/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: snapshot-controller\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/spegel/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app spegel\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: spegel\n  valuesFrom:\n    - kind: ConfigMap\n      name: spegel-values\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/spegel/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: spegel-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/spegel/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/valuesFrom/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/spegel/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: spegel\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.7.0\n  url: oci://ghcr.io/spegel-org/helm-charts/spegel\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/spegel/app/values.yaml",
    "content": "grafanaDashboard:\n  enabled: true\nservice:\n  registry:\n    hostPort: 29999\nserviceMonitor:\n  enabled: true\nspegel:\n  containerdSock: /run/containerd/containerd.sock\n  containerdRegistryConfigPath: /etc/cri/conf.d/hosts\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/spegel/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: spegel\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/spegel/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: spegel\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/tetragon/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: tetragon\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: tetragon\n  valuesFrom:\n    - kind: ConfigMap\n      name: tetragon-values\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/tetragon/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: tetragon-values\n    files:\n      - values.yaml=values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/tetragon/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/valuesFrom/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/tetragon/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: tetragon\n  namespace: kube-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.6.0\n  url: oci://ghcr.io/cilium/charts/tetragon\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/tetragon/app/values.yaml",
    "content": "enabled: true\nimagePullPolicy: IfNotPresent\nimagePullSecrets: []\nserviceAccount:\n  create: true\n  annotations: {}\n  name: \"\"\npodAnnotations: {}\npodSecurityContext: {}\nnodeSelector: {}\ntolerations:\n- operator: Exists\naffinity:\n  nodeAffinity:\n    requiredDuringSchedulingIgnoredDuringExecution:\n      nodeSelectorTerms:\n      - matchExpressions:\n        - key: kubernetes.io/arch\n          operator: In\n          values:\n          - amd64\nextraHostPathMounts: []\nextraConfigmapMounts: []\ndaemonSetAnnotations: {}\nextraVolumes: []\nupdateStrategy: {}\ndaemonSetLabelsOverride: {}\nselectorLabelsOverride: {}\npodLabelsOverride: {}\nserviceLabelsOverride: {}\n\n# Set DNS policy for tetragon pods.\n#\n# Recommended DNS policy for tetragon pod depends on whether the export container\n# needs to resolve external DNS names (e.g. an S3 URL) or internal ones (e.g. a Kubernetes\n# DNS name for elasticsearch service).\n#\n# - For external DNS names, use \"Default\" so that the export container continues to function\n#   properly in case there is a connectivity issue between the export container and core-dns.\n# - For internal DNS names, use \"ClusterFirstWithHostNet\" so that the export container can\n#   resolve them.\n#\n# https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy\ndnsPolicy: Default\n\n# exportDirectory specifies directory to put Hubble and FGS JSON export files.\nexportDirectory: \"/var/run/cilium/tetragon\"\n# exportFileRotationInterval specifies file creation interval for hubble-export-s3.\nexportFileCreationInterval: \"120s\"\n\n#\n# Configures whether Tetragon pods run on the host network.\n#\n# IMPORTANT: Tetragon must be on the host network for the process visibility to\n# function properly.\n#\nhostNetwork: true\n\ntetragon:\n  enabled: true\n  image:\n    override: ~\n    repository: quay.io/cilium/tetragon\n  resources: {}\n  extraArgs: {}\n  extraEnv: []\n  # extraEnv:\n  #   - name: foo\n  #     value: bar\n  extraVolumeMounts: []\n  securityContext:\n    privileged: true\n\n  # Tetragon puts processes in an LRU cache. The cache is used to find ancestors for subsequently exec'ed\n  # processes.\n  processCacheSize: 65536\n\n  # JSON export filename. Set it to an empty string to disable JSON export altogether.\n  exportFilename: tetragon.log\n\n  # Size in megabytes at which to rotate JSON export files.\n  exportFileMaxSizeMB: 10\n\n  # Number of rotated files to retain.\n  exportFileMaxBackups: 5\n\n  # Compress rotated JSON export files.\n  exportFileCompress: false\n\n  # Rate-limit event export (events per minute), Set to -1 to export all events.\n  exportRateLimit: -1\n\n  # Allowlist for JSON export. For example, to export only process_connect events from\n  # the default namespace:\n  #\n  # exportAllowList: |\n  #   {\"namespace\":[\"default\"],\"event_set\":[\"PROCESS_EXEC\"]}\n  exportAllowList: |-\n    {\"event_set\":[\"PROCESS_EXEC\", \"PROCESS_EXIT\", \"PROCESS_KPROBE\"]}\n  # Denylist for JSON export. For example, to exclude exec events that look similar to\n  # Kubernetes health checks and all the events from kube-system namespace and the host:\n  #\n  # exportDenyList: |\n  #   {\"health_check\":true}\n  #   {\"namespace\":[\"kube-system\",\"\"]}\n  #\n  exportDenyList: |-\n    {\"health_check\":true}\n    {\"namespace\":[\"\", \"cilium\", \"kube-system\"]}\n  # Filters to include or exclude fields from Tetragon events. Without any filters, all\n  # fields are included by default. The presence of at least one inclusion filter implies\n  # default-exclude (i.e. any fields that don't match an inclusion filter will be\n  # excluded). Field paths are expressed using dot notation like \"a.b.c\" and multiple\n  # field paths can be separated by commas like \"a.b.c,d,e.f\". An optional \"event_set\" may\n  # be specified to apply the field filter to a specific set of events.\n  #\n  # For example, to exclude the \"parent\" field from all events and include the \"process\"\n  # field in PROCESS_KPROBE events while excluding all others:\n  #\n  # fieldFilters: |\n  #   {\"fields\": \"parent\", \"action\": \"EXCLUDE\"}\n  #   {\"event_set\": [\"PROCESS_KPROBE\"], \"fields\": \"process\", \"action\": \"INCLUDE\"}\n  #\n  fieldFilters: |-\n    {}\n  # Access Kubernetes API to associate Tetragon events with Kubernetes pods.\n  enableK8sAPI: true\n\n  # Access Cilium API to associate Tetragon events with Cilium endpoints and DNS cache.\n  enableCiliumAPI: true\n\n  # enableProcessCred enables Capabilities visibility in exec and kprobe events.\n  enableProcessCred: true\n\n  # enableProcessNs enables Namespaces visibility in exec and kprobe events.\n  enableProcessNs: true\n\n  # Set --btf option to explicitly specify an absolute path to a btf file. For advanced users only.\n  btf: \"\"\n\n  # Override the command. For advanced users only.\n  commandOverride: []\n\n  # Override the arguments. For advanced users only.\n  argsOverride: []\n\n  prometheus:\n    # -- Whether to enable exposing Tetragon metrics.\n    enabled: true\n    # -- The address at which to expose metrics. Set it to \"\" to expose on all available interfaces.\n    address: \"\"\n    # -- The port at which to expose metrics.\n    port: 2112\n    serviceMonitor:\n      # -- Whether to create a 'ServiceMonitor' resource targeting the 'tetragon' pods.\n      enabled: true\n      # -- The set of labels to place on the 'ServiceMonitor' resource.\n      labelsOverride: {}\n  grpc:\n    # -- Whether to enable exposing Tetragon gRPC.\n    enabled: true\n    # -- The address at which to expose gRPC. Examples: localhost:54321, unix:///var/run/tetragon/tetragon.sock\n    address: \"localhost:54321\"\n  gops:\n    # -- The address at which to expose gops.\n    address: \"localhost\"\n    # -- The port at which to expose gops.\n    port: 8118\n  # Enable policy filter. This is required for K8s namespace filtering.\n  # NB: this is currently a work-in-progress feature\n  enablePolicyFilter: false\ntetragonOperator:\n  # -- Enable the tetragon-operator component (required).\n  enabled: true\n\n  # -- tetragon-operator image.\n  image:\n    override: ~\n    repository: quay.io/cilium/tetragon-operator\n    # tetragon-operator image-digest\n    suffix: \"\"\n\nexport:\n  # \"stdout\". \"\" to disable.\n  mode: \"stdout\"\n  resources: {}\n  extraArgs: {}\n  extraEnv: []\n  # extraEnv:\n  #   - name: foo\n  #     value: bar\n  extraVolumeMounts: []\n  securityContext: {}\n\n  # Override the command. For advanced users only.\n  commandOverride: []\n\n  # Override the arguments. For advanced users only.\n  argsOverride: []\n\n  # filenames defines list of files for fluentd to tail and export.\n  filenames:\n  - tetragon.log\n  # stdout specific exporter settings\n  stdout:\n    extraEnv: []\n    # extraEnv:\n    #   - name: foo\n    #     value: bar\n\n    # * When enabledCommand=true and commandOverride is not set, the command inserted will be hubble-export-stdout.\n    #   This supports the default for the current deployment instructions to deploy stdout-export sidecar container.\n    # * When enabledCommand=true and commandOverride override is set, the command inserted will be the value of commandOverride.\n    #   This is useful for inserting another sidecar container that requires a command override.\n    # * When enabledCommand=false, no command will be specified in the manifest and container's default command will take over.\n    enabledCommand: true\n    # * When enabledArgs=true and argsOverride is not set, the args inserted will be the default ones for export-stdout.\n    # * When enabledArgs=true and argsOverride override is set, the args value inserted will be the value of argsOverride.\n    #   This is useful for inserting another sidecar container that requires args override.\n    # * When enabledArgs=false, no command will be specified in the manifest and container's default args value will take over.\n    enabledArgs: true\n    # specific manifest command to use\n    commandOverride: []\n    # specific manifest args to use\n    argsOverride: []\n    # Extra volume mounts to add to stdout export pod\n    extraVolumeMounts: []\n    image:\n      override: ~\n      repository: quay.io/cilium/hubble-export-stdout\n"
  },
  {
    "path": "kubernetes/apps/base/kube-system/tetragon/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: tetragon\n  namespace: kube-system\nspec:\n  path: \"./apps/base/kube-system/tetragon/app\"\n  wait: true\n  targetNamespace: kube-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: tetragon\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/README.md",
    "content": "# Cloudflare DDNS\n\nhttps://github.com/hotio/docker-cloudflare-ddns\n\nUse the following command to generate the secret with the required fields for the deployment.\n\n```bash\nkubectl create secret generic cloudflare-ddns \\\n  --from-literal=api-token=\"\" \\\n  --from-literal=zones=\"owncloud.ai\" \\\n  --from-literal=hosts=\"owncloud.ai\" \\\n  --from-literal=record-types=\"A;A;AAAA\" \\\n  --namespace network-system --dry-run -o yaml > .secrets/k8s-secret-cloudflare-ddns.yaml\n```\n\n# Cert-Manager\n\n```bash\nkubectl create secret generic cloudflare-cert-manager-token \\\n  --from-literal=api-token=\"\" \\\n  --namespace network-system --dry-run -o yaml > .secrets/k8s-secret-cloudflare-cert-manager-token.yaml\n```\n\n# Oauth2-Proxy\n\nhttps://github.com/oauth2-proxy/oauth2-proxy/blob/master/docs/configuration/configuration.md\n\nRun the following command to generate a secure cookie secret:\n\n```bash\npython -c 'import os,base64; print base64.b64encode(os.urandom(16))'\n```\n\nThen, create the Kubernetes secret, substituting the highlighted values for your cookie secret, your GitHub client ID, and your GitHub secret key:\n\n```bash\nkubectl -n network-system create secret generic oauth2-proxy \\\n  --from-literal=cookie-secret=\"\" \\\n  --from-literal=client-id=\"\" \\\n  --from-literal=client-secret=\"\" --dry-run -o yaml > .secrets/k8s-secret-github-oauth2.yaml\n```\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/clusterissuer-prod.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/clusterissuer_v1.json\napiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-prod\nspec:\n  acme:\n    server: https://acme-v02.api.letsencrypt.org/directory\n    email: ${PRIVATE_EMAIL}\n    privateKeySecretRef:\n      name: letsencrypt-prod\n    solvers:\n      - dns01:\n          cloudflare:\n            email: ${PRIVATE_EMAIL}\n            apiTokenSecretRef:\n              name: cert-manager-cloudflare-token\n              key: CERT_MANAGER_CLOUDFLARE_API_TOKEN\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: cert-manager-cloudflare-token\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: cert-manager-cloudflare-token\n    template:\n      data:\n        CERT_MANAGER_CLOUDFLARE_API_TOKEN: \"{{ .CERT_MANAGER_CLOUDFLARE_API_TOKEN }}\"\n  dataFrom:\n    - extract:\n        key: cloudflare\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: cert-manager\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/20842/revisions/3/download\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app cert-manager\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: cert-manager\n  valuesFrom:\n    - kind: ConfigMap\n      name: cert-manager-values\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - clusterissuer-prod.yaml\n  - externalsecret.yaml\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n  - prometheusrule.yaml\n\nconfigMapGenerator:\n  - name: cert-manager-values\n    namespace: network-system\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: cert-manager\n  namespace: network-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: v1.20.2\n  url: oci://quay.io/jetstack/charts/cert-manager\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/prometheusrule.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/prometheusrule_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  name: cert-manager-rules\nspec:\n  groups:\n    - name: cert-manager.rules\n      rules:\n        - alert: CertManagerAbsent\n          expr: |-\n            absent(up{job=\"cert-manager\"})\n          for: 30m\n          annotations:\n            summary: >-\n              Cert Manager has disappeared from Prometheus service discovery\n          labels:\n            severity: critical\n\n    - name: certificates\n      rules:\n        - alert: CertManagerCertExpirySoon\n          expr: |-\n            avg by (exported_namespace, namespace, name) (certmanager_certificate_expiration_timestamp_seconds - time()) < (21 * 24 * 3600)\n          for: 15m\n          annotations:\n            summary: >-\n              The cert {{ $labels.name }} is {{ $value | humanizeDuration }} from expiry, it should have renewed over a week ago\n          labels:\n            severity: critical\n\n        - alert: CertManagerCertNotReady\n          expr: |-\n            max by (name, exported_namespace, namespace, condition) (certmanager_certificate_ready_status{condition!=\"True\"} == 1)\n          for: 1h\n          annotations:\n            summary: >-\n              The cert {{ $labels.name }} is not ready to serve traffic\n          labels:\n            severity: warning\n\n        - alert: CertManagerHittingRateLimits\n          expr: |-\n            sum by (host) (rate(certmanager_http_acme_client_request_count{status=\"429\"}[5m])) > 0\n          for: 15m\n          annotations:\n            summary: >-\n              Cert manager hitting LetsEncrypt rate limits\n          labels:\n            severity: critical\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/app/values.yaml",
    "content": "---\ncrds:\n  enabled: true\n# webhook:\n#   url:\n#     host: cert-manager-webhook.network-system.svc\nglobal:\n  # Set the verbosity of cert-manager. Range of 0 - 6 with 6 being the most verbose.\n  logLevel: 2\n  priorityClassName: platform-cluster-critical\n  leaderElection:\n    # Override the namespace used to store the ConfigMap for leader election\n    namespace: 'network-system'\nextraArgs:\n  # Use this flag to set a namespace that cert-manager will use to store\n  # supporting resources required for each ClusterIssuer (default is kube-system)\n  - --cluster-resource-namespace=network-system\n  # When this flag is enabled, secrets will be automatically removed when the certificate resource is deleted\n  - --enable-certificate-owner-ref=true\n  - --dns01-recursive-nameservers=https://1.1.1.1:443/dns-query,https://1.0.0.1:443/dns-query\n  - --dns01-recursive-nameservers-only\n  - --default-issuer-name=letsencrypt-prod\n  - --default-issuer-kind=ClusterIssuer\nprometheus:\n  servicemonitor:\n    enabled: true\npodDisruptionBudget:\n  enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cert-manager/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cert-manager\n  namespace: network-system\nspec:\n  healthChecks:\n    - apiVersion: helm.toolkit.fluxcd.io/v2\n      kind: HelmRelease\n      name: cert-manager\n      namespace: network-system\n    - apiVersion: cert-manager.io/v1\n      kind: ClusterIssuer\n      name: letsencrypt-prod\n  healthCheckExprs:\n    - apiVersion: cert-manager.io/v1\n      kind: ClusterIssuer\n      failed: status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'False')\n      current: status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'True')\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n  path: \"./apps/base/network-system/cert-manager/app\"\n  wait: false\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: cert-manager\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cloudflare-tunnel/app/dnsendpoint.yaml",
    "content": "---\n# This resource defines a DNSEndpoint for the ingress gateway with a CNAME record pointing to the Cloudflare Argo tunnel.\napiVersion: externaldns.k8s.io/v1alpha1\nkind: DNSEndpoint\nmetadata:\n  name: cloudflare-tunnel\n  namespace: networking\n  annotations:\n    external-dns.alpha.kubernetes.io/target: \"external.${CLUSTER_DOMAIN}\"\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  endpoints:\n    - dnsName: \"external.${CLUSTER_DOMAIN}\"\n      recordType: CNAME\n      targets:\n        - \"${CLOUDFLARED_TUNNEL_ID}.cfargotunnel.com\"\n---\n# This resource defines a DNSEndpoint for the Kubernetes API server with a CNAME record pointing to the Cloudflare Argo tunnel.\n# It is used for exposing the kube-apiserver endpoint via Cloudflared.\napiVersion: externaldns.k8s.io/v1alpha1\nkind: DNSEndpoint\nmetadata:\n  name: cloudflared-api\n  namespace: networking\n  annotations:\n    external-dns.alpha.kubernetes.io/target: \"api.${CLUSTER_DOMAIN}\"\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  endpoints:\n    - dnsName: \"api.${CLUSTER_DOMAIN}\"\n      recordType: CNAME\n      targets:\n        - \"external.${CLUSTER_DOMAIN}\"\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cloudflare-tunnel/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: cloudflare-tunnel\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: cloudflare-tunnel-secret\n    template:\n      data:\n        TUNNEL_TOKEN: |-\n          {{ toJson (dict \"a\" .CLOUDFLARED_ACCOUNT_TAG \"t\" .CLOUDFLARED_TUNNEL_ID \"s\" .CLOUDFLARED_TUNNEL_SECRET) | b64enc }}\n  dataFrom:\n    - extract:\n        key: cloudflare\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cloudflare-tunnel/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: cloudflare-tunnels\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/17457/revisions/6/download\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cloudflare-tunnel/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app cloudflare-tunnel\n  namespace: network-system\nspec:\n  interval: 30m\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        replicas: 2\n        strategy: RollingUpdate\n        annotations:\n          reloader.stakater.com/auto: \"true\"\n        containers:\n          app:\n            image:\n              repository: docker.io/cloudflare/cloudflared\n              tag: 2026.5.0@sha256:59bab8d3aceec09bf6bdb07d6beca0225ca5cd7ab79436a87ea97978fe1dc4f9\n            env:\n              NO_AUTOUPDATE: true\n              TUNNEL_METRICS: 0.0.0.0:8080\n              TUNNEL_TRANSPORT_PROTOCOL: quic\n              TUNNEL_POST_QUANTUM: true\n            envFrom:\n              - secretRef:\n                  name: cloudflare-tunnel-secret\n            args:\n              - tunnel\n              - run\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /ready\n                    port: &port 8080\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 5m\n                memory: 10Mi\n              limits:\n                memory: 256Mi\n    defaultPodOptions:\n      topologySpreadConstraints:\n        - maxSkew: 1\n          topologyKey: kubernetes.io/hostname\n          whenUnsatisfiable: DoNotSchedule\n          labelSelector:\n            matchLabels:\n              app.kubernetes.io/name: cloudflare-tunnel\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    serviceMonitor:\n      app:\n        serviceName: *app\n        endpoints:\n          - port: http\n            scheme: http\n            path: /metrics\n            interval: 1m\n            scrapeTimeout: 10s\n    configMaps:\n      config:\n        data:\n          config.yaml: |-\n            ingress:\n              - hostname: \"api.${CLUSTER_DOMAIN}\"\n                service: tcp://kubernetes.default.svc.cluster.local:443\n                originRequest:\n                  proxyType: socks\n              - hostname: \"*.${CLUSTER_DOMAIN}\"\n                originRequest:\n                  http2Origin: true\n                  keepAliveTimeout: 3600s\n                  originServerName: external.${CLUSTER_DOMAIN}\n                  tcpKeepAlive: 7200s\n                service: https://envoy-external.network-system.svc.cluster.local:443\n              - service: http_status:404\n    persistence:\n      config-file:\n        type: configMap\n        identifier: config\n        globalMounts:\n          - path: /etc/cloudflared/config.yaml\n            subPath: config.yaml\n            readOnly: true\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cloudflare-tunnel/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - dnsendpoint.yaml\n  - externalsecret.yaml\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/cloudflare-tunnel/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cloudflare-tunnel\n  namespace: network-system\nspec:\n  path: \"./apps/base/network-system/cloudflare-tunnel/app\"\n  wait: true\n  dependsOn:\n    - name: external-dns\n      namespace: network-system\n    - name: onepassword\n      namespace: external-secrets\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: cloudflare-tunnel\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex/app/README.md",
    "content": "# Dex\n\nEnter valid secrets into the values.yaml and use the following command to generate the secret, then use sealed secrets to encrypt these values to be used within the helm release resource.\n\n```bash\nkubectl create secret generic dex-helm-values --from-file=values.yaml=config/dex/values.yaml --dry-run=client -n network -o yaml > secret.yaml\n```\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app dex\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: dex\n      version: 0.24.0\n      sourceRef:\n        kind: HelmRepository\n        name: dex-chart\n        namespace: flux-system\n      interval: 10m\n  valuesFrom:\n    - kind: ConfigMap\n      name: dex-values\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: dex\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'dex.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: dex\n          port: 5556\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - httproute.yaml\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: dex-values\n    namespace: network-system\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/valuesFrom/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex/app/values.yaml",
    "content": "image:\n  repository: dexidp/dex\n  tag: v2.45.1\nenv:\n  KUBERNETES_POD_namespace: network-system\nconfig:\n  issuer: 'https://dex.${CLUSTER_DOMAIN}'\n  storage:\n    type: kubernetes\n    config:\n      inCluster: true\n  oauth2:\n    alwaysShowLoginScreen: false\n    responseTypes: ['code', 'token', 'id_token']\n    skipApprovalScreen: true\n  web:\n    http: 0.0.0.0:5556\n  frontend:\n    theme: 'tectonic'\n    issuer: 'Homelab SSO'\n    issuerUrl: 'https://dex.${CLUSTER_DOMAIN}'\n    logoUrl: https://raw.githubusercontent.com/raspbernetes/docs/master/website/static/img/logo.png\n  expiry:\n    signingKeys: '6h'\n    idTokens: '24h'\n  logger:\n    level: debug\n    format: json\n  # Disable default email auth and only use oauth2 providers configured as connectors\n  enablePasswordDB: false\n  # Remember you can have multiple connectors of the same 'type' (with different 'id's)\n  # If you need e.g. logins with groups for two different Microsoft 'tenants'\n  connectors:\n    # GitHub configure 'OAuth Apps' -> 'New OAuth App', add callback URL\n    # https://github.com/settings/developers\n    - type: github\n      id: github\n      name: GitHub\n      config:\n        clientID: '${DEX_GITHUB_CLIENT_ID}'\n        clientSecret: '${DEX_GITHUB_CLIENT_SECRET}'\n        redirectURI: 'https://dex.${CLUSTER_DOMAIN}/callback'\n        # 'orgs' can be used to map groups from Github\n        # https://github.com/coreos/dex/blob/master/Documentation/connectors/github.md\n        orgs:\n          - name: raspbernetes\n  # The 'name' must match the k8s API server's 'oidc-client-id'\n  staticClients:\n    - id: oauth2-proxy\n      name: 'oauth2-proxy'\n      secret: '${DEX_OAUTH2_PROXY_SECRET}'\n      redirectURIs:\n        - 'https://alert-manager.${CLUSTER_DOMAIN}/oauth2/callback'\n        - 'https://hass.${CLUSTER_DOMAIN}/oauth2/callback'\n        - 'https://kiali.${CLUSTER_DOMAIN}/oauth2/callback'\n        - 'https://prometheus.${CLUSTER_DOMAIN}/oauth2/callback'\n        - 'https://sealed-secrets.${CLUSTER_DOMAIN}/oauth2/callback'\n    - id: grafana\n      name: 'grafana'\n      secret: '${DEX_GRAFANA_SECRET}'\n      redirectURIs:\n        - 'https://grafana.${CLUSTER_DOMAIN}/login/generic_oauth'\n    - id: dex-k8s-authenticator\n      name: dex-k8s-authenticator\n      secret: ${DEX_K8S_CLIENT_SECRET}\n      redirectURIs:\n        - https://login.${CLUSTER_DOMAIN}/callback\n    - id: LitmusPortalAuthBackend\n      name: 'LitmusPortalAuthBackend'\n      secret: '${DEX_LITMUS_SECRET}'\n      redirectURIs:\n        - '/auth/dex/callback'\n        - 'http://localhost:8080/auth/dex/callback' # Included for local testing purposes\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: dex\n  namespace: network-system\nspec:\n  path: \"./apps/base/network-system/dex/app\"\n  wait: true\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n    - name: cert-manager\n      namespace: network-system\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: dex\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/clusterrolebinding.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: k8s-admins-binding\nroleRef:\n  kind: ClusterRole\n  name: cluster-admin\n  apiGroup: rbac.authorization.k8s.io\nsubjects:\n- kind: Group\n  name: raspbernetes:k8s-admins\n  apiGroup: rbac.authorization.k8s.io\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: k8s-guests-binding\nroleRef:\n  kind: ClusterRole\n  name: view\n  apiGroup: rbac.authorization.k8s.io\nsubjects:\n- kind: Group\n  name: raspbernetes:k8s-guests\n  apiGroup: rbac.authorization.k8s.io\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app dex-k8s-authenticator\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        replicas: 1\n        strategy: RollingUpdate\n        containers:\n          app:\n            image:\n              repository: ghcr.io/xunholy/dex-k8s-authenticator\n              tag: 9e61a68b98fc980275a966137927b79e0d575103\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /healthz\n                    port: &port 5555\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n                memory: 32Mi\n              limits:\n                memory: 128Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    configMaps:\n      config:\n        data:\n          config.yaml: |-\n            listen: http://0.0.0.0:5555\n            web_path_prefix: /\n            debug: true\n            clusters:\n              - name: kubernetes\n                short_description: \"Cluster 00\"\n                description: \"Cluster Login\"\n                client_secret: \"${DEX_K8S_CLIENT_SECRET}\"\n                issuer: \"https://dex.${CLUSTER_DOMAIN}\"\n                k8s_master_uri: https://${CLUSTER_CONTROLPLANE_VIP}:6443\n                client_id: \"${DEX_K8S_CLIENT_ID}\"\n                redirect_uri: https://login.${CLUSTER_DOMAIN}/callback\n                k8s_ca_pem: |\n                  -----BEGIN CERTIFICATE-----\n                  MIIBijCCATCgAwIBAgIRAKe1fimhdjgMm+tAfHtovvowCgYIKoZIzj0EAwIwFTET\n                  MBEGA1UEChMKa3ViZXJuZXRlczAeFw0yNTEwMTEwMzEzMTdaFw0zNTEwMDkwMzEz\n                  MTdaMBUxEzARBgNVBAoTCmt1YmVybmV0ZXMwWTATBgcqhkjOPQIBBggqhkjOPQMB\n                  BwNCAATlqT+4DaHxabdX4JxwKstgqPkuR/1+H7RZgOmA1n/jjQP3jjKDxqMIzpbQ\n                  i6P/BFuYMY3L04kEz7iYqWMxa9byo2EwXzAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0l\n                  BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\n                  BBYEFAMIRFQ/gcCC4A7dGhyWciGP0c9yMAoGCCqGSM49BAMCA0gAMEUCIGj+4ye6\n                  c2F26IJW75btkhtNGtonZxzgCahoguVKz9lPAiEApKt6F2obZ9axsIytkCtPph3R\n                  eL9OYSE6Q2PF5CvX5gI=\n                  -----END CERTIFICATE-----\n    persistence:\n      config:\n        type: configMap\n        identifier: config\n        globalMounts:\n          - path: /app/config.yaml\n            subPath: config.yaml\n            readOnly: true\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: dex-k8s-authenticator\n  namespace: network-system\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'login.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: dex-k8s-authenticator\n          port: 5555\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - httproute.yaml\n  - clusterrolebinding.yaml\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/Dockerfile",
    "content": "FROM golang:1.25-alpine AS builder\n\nRUN apk add --no-cache ca-certificates\n\nWORKDIR /src\n\nCOPY go.mod go.sum ./\nRUN go mod download\n\nCOPY *.go ./\n\nRUN CGO_ENABLED=0 go build -ldflags=\"-s -w\" -o /app/bin/dex-k8s-authenticator .\n\nFROM alpine:3.21\n\nRUN apk add --no-cache ca-certificates tini \\\n    && addgroup -g 1000 -S app \\\n    && adduser -u 1000 -S app -G app\n\nWORKDIR /app\n\nCOPY --from=builder /app/bin/dex-k8s-authenticator /app/bin/dex-k8s-authenticator\nCOPY html/ /app/html/\nCOPY templates/ /app/templates/\nCOPY entrypoint.sh /entrypoint.sh\n\nRUN chmod +x /entrypoint.sh && mkdir -p /certs && chown -R app:app /app /certs\n\nUSER 1000:1000\n\nEXPOSE 5555\n\nENTRYPOINT [\"/sbin/tini\", \"--\", \"/entrypoint.sh\"]\nCMD [\"--config\", \"/app/config.yaml\"]\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/dex-auth.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"path\"\n\t\"time\"\n\n\toidc \"github.com/coreos/go-oidc/v3/oidc\"\n\t\"os\"\n\t\"github.com/spf13/cast\"\n\t\"golang.org/x/oauth2\"\n)\n\nconst exampleAppState = \"Vgn2lp5QnymFtLntKX5dM8k773PwcM87T4hQtiESC1q8wkUBgw5D3kH0r5qJ\"\n\nfunc (cluster *Cluster) oauth2Config() *oauth2.Config {\n\n\treturn &oauth2.Config{\n\t\tClientID:     cluster.Client_ID,\n\t\tClientSecret: cluster.Client_Secret,\n\t\tEndpoint:     cluster.Provider.Endpoint(),\n\t\tScopes:       cluster.Scopes,\n\t\tRedirectURL:  cluster.Redirect_URI,\n\t}\n}\n\nfunc (config *Config) handleIndex(w http.ResponseWriter, r *http.Request) {\n\n\tif len(config.Clusters) == 1 && r.URL.String() == config.Web_Path_Prefix {\n\t\thttp.Redirect(w, r, path.Join(config.Web_Path_Prefix, \"login\", config.Clusters[0].Name), http.StatusSeeOther)\n\t} else {\n\t\trenderIndex(w, config)\n\t}\n}\n\nfunc (cluster *Cluster) handleLogin(w http.ResponseWriter, r *http.Request) {\n\tlog.Printf(\"Handling login-uri for: %s\", cluster.Name)\n\tauthCodeURL := cluster.oauth2Config().AuthCodeURL(exampleAppState, oauth2.AccessTypeOffline)\n\tif cluster.Connector_ID != \"\" {\n\t\tlog.Printf(\"Using dex connector with id %#q\", cluster.Connector_ID)\n\t\tauthCodeURL = fmt.Sprintf(\"%s&connector_id=%s\", authCodeURL, cluster.Connector_ID)\n\t}\n\tlog.Printf(\"Redirecting post-loginto: %s\", authCodeURL)\n\thttp.Redirect(w, r, authCodeURL, http.StatusSeeOther)\n}\n\nfunc (cluster *Cluster) handleCallback(w http.ResponseWriter, r *http.Request) {\n\tvar (\n\t\terr      error\n\t\ttoken    *oauth2.Token\n\t\tIdpCaPem string\n\t)\n\n\t// An error message to that presented to the user\n\tuserErrorMsg := \"Invalid token request\"\n\n\tlog.Printf(\"Handling callback for: %s\", cluster.Name)\n\n\tctx := oidc.ClientContext(r.Context(), cluster.Client)\n\toauth2Config := cluster.oauth2Config()\n\tswitch r.Method {\n\tcase \"GET\":\n\t\t// Authorization redirect callback from OAuth2 auth flow.\n\t\tif errMsg := r.FormValue(\"error\"); errMsg != \"\" {\n\t\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\t\tlog.Printf(\"handleCallback: request error. error: %s, error_description: %s\", errMsg, r.FormValue(\"error_description\"))\n\t\t\treturn\n\t\t}\n\t\tcode := r.FormValue(\"code\")\n\t\tif code == \"\" {\n\t\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\t\tlog.Printf(\"handleCallback: no code in request: %q\", r.Form)\n\t\t\treturn\n\t\t}\n\t\tif state := r.FormValue(\"state\"); state != exampleAppState {\n\t\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\t\tlog.Printf(\"handleCallback: expected state %q got %q\", exampleAppState, state)\n\t\t\treturn\n\t\t}\n\t\ttoken, err = oauth2Config.Exchange(ctx, code)\n\tcase \"POST\":\n\t\t// Form request from frontend to refresh a token.\n\t\trefresh := r.FormValue(\"refresh_token\")\n\t\tif refresh == \"\" {\n\t\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\t\tlog.Printf(\"handleCallback: no refresh_token in request: %q\", r.Form)\n\t\t\treturn\n\t\t}\n\t\tt := &oauth2.Token{\n\t\t\tRefreshToken: refresh,\n\t\t\tExpiry:       time.Now().Add(-time.Hour),\n\t\t}\n\t\ttoken, err = oauth2Config.TokenSource(ctx, t).Token()\n\tdefault:\n\t\t// Return non-HTML error for non GET/POST requests which probably wasn't executed by browser\n\t\thttp.Error(w, fmt.Sprintf(\"Method not implemented: %s\", r.Method), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tif err != nil {\n\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\tlog.Printf(\"handleCallback: failed to get token: %v\", err)\n\t\treturn\n\t}\n\n\trawIDToken, ok := token.Extra(\"id_token\").(string)\n\tif !ok {\n\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\tlog.Printf(\"handleCallback: no id_token in response: %q\", token)\n\t\treturn\n\t}\n\n\tidToken, err := cluster.Verifier.Verify(r.Context(), rawIDToken)\n\tif err != nil {\n\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\tlog.Printf(\"handleCallback: failed to verify ID token: %q, err: %v\", rawIDToken, err)\n\t\treturn\n\t}\n\tvar claims json.RawMessage\n\tif err = idToken.Claims(&claims); err != nil {\n\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\tlog.Printf(\"handleCallback: failed to unmarshal json payload of ID token into claims: %v\", err)\n\t\treturn\n\t}\n\n\tbuff := new(bytes.Buffer)\n\tif err = json.Indent(buff, []byte(claims), \"\", \"  \"); err != nil {\n\t\tcluster.renderHTMLError(w, userErrorMsg, http.StatusBadRequest)\n\t\tlog.Printf(\"handleCallback: failed to indent json:  %v\", err)\n\t\treturn\n\n\t}\n\n\tif cluster.Config.IDP_Ca_Pem != \"\" {\n\t\tIdpCaPem = cluster.Config.IDP_Ca_Pem\n\t} else if cluster.Config.IDP_Ca_Pem_File != \"\" {\n\t\tcontent, err := os.ReadFile(cluster.Config.IDP_Ca_Pem_File)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Failed to load CA from file %s, %s\", cluster.Config.IDP_Ca_Pem_File, err)\n\t\t}\n\t\tIdpCaPem = cast.ToString(content)\n\t}\n\n\tcluster.renderToken(w, rawIDToken, token.RefreshToken,\n\t\tcluster.Config.IDP_Ca_URI,\n\t\tIdpCaPem,\n\t\tcluster.Config.Logo_Uri,\n\t\tcluster.Config.Web_Path_Prefix,\n\t\tcluster.Config.Kubectl_Version,\n\t\tbuff.Bytes())\n}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/entrypoint.sh",
    "content": "#!/bin/sh\n\nif [ -n \"$(ls -A /certs)\" ]; then\n  cp -L /certs/*.crt /usr/local/share/ca-certificates/ 2>/dev/null\n  update-ca-certificates\nfi\n\nexec /app/bin/dex-k8s-authenticator \"$@\"\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/go.mod",
    "content": "module github.com/xunholy/dex-k8s-authenticator\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/coreos/go-oidc/v3 v3.18.0\n\tgithub.com/spf13/cast v1.7.1\n\tgithub.com/spf13/cobra v1.9.1\n\tgithub.com/spf13/viper v1.20.1\n\tgolang.org/x/oauth2 v0.36.0\n)\n\nrequire (\n\tgithub.com/fsnotify/fsnotify v1.8.0 // indirect\n\tgithub.com/go-jose/go-jose/v4 v4.1.4 // indirect\n\tgithub.com/go-viper/mapstructure/v2 v2.4.0 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.3 // indirect\n\tgithub.com/sagikazarmark/locafero v0.7.0 // indirect\n\tgithub.com/sourcegraph/conc v0.3.0 // indirect\n\tgithub.com/spf13/afero v1.12.0 // indirect\n\tgithub.com/spf13/pflag v1.0.6 // indirect\n\tgithub.com/subosito/gotenv v1.6.0 // indirect\n\tgo.uber.org/multierr v1.11.0 // indirect\n\tgolang.org/x/sys v0.38.0 // indirect\n\tgolang.org/x/text v0.31.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/go.sum",
    "content": "github.com/coreos/go-oidc/v3 v3.18.0 h1:V9orjXynvu5wiC9SemFTWnG4F45v403aIcjWo0d41+A=\ngithub.com/coreos/go-oidc/v3 v3.18.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=\ngithub.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=\ngithub.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=\ngithub.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=\ngithub.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=\ngithub.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=\ngithub.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=\ngithub.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=\ngithub.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=\ngithub.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=\ngithub.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=\ngithub.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=\ngithub.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=\ngithub.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=\ngithub.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=\ngithub.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=\ngithub.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=\ngithub.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=\ngithub.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=\ngithub.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=\ngithub.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngolang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=\ngolang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=\ngolang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=\ngolang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=\ngolang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/html/static/main.css",
    "content": "* {\n  box-sizing: border-box;\n}\n\nbody {\n  margin: 0;\n  font-family: Arial;\n}\n\nh3 { font-size: 16px; }\n\npre {\n  background-color: #eff0f1;\n  padding: 5px;\n  white-space: pre-wrap;\n  overflow-wrap: break-word;\n}\n\n.dex-container {\n  color: #333;\n  margin: 45px auto;\n  max-width: 500px;\n  min-width: 320px;\n  text-align: center;\n}\n\n.dex-kubeconfig-container {\n  color: #333;\n  margin: 45px auto;\n  max-width: 90%;\n  min-width: 320px;\n  text-align: left;\n}\n\n.dex-btn {\n  border-radius: 4px;\n  border: 0;\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 1px rgba(0, 0, 0, 0.25);\n  cursor: pointer;\n  font-size: 16px;\n  padding: 0;\n}\n\n.dex-btn:focus {\n  outline: none;\n}\n\n.dex-btn:active {\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  outline: none;\n}\n\n.dex-btn-icon {\n  background-position: center;\n  background-repeat: no-repeat;\n  background-size: 24px;\n  border-radius: 4px 0 0 4px;\n  float: left;\n  height: 36px;\n  margin-right: 5px;\n  width: 36px;\n}\n\n.dex-btn-icon--local {\n  background-color: #84B6EF;\n  background-image: url(./button.svg);\n}\n\n.dex-btn-text {\n  font-weight: 600;\n  line-height: 36px;\n  padding: 6px 12px;\n  text-align: center;\n}\n\n.dex-separator {\n  color: #999;\n}\n\n.dex-error-box {\n  background-color: #DD1327;\n  color: #fff;\n  font-size: 14px;\n  font-weight: normal;\n  max-width: 320px;\n  padding: 4px 0;\n}\n\n.dex-error-box {\n  margin: 20px auto;\n}\n\ndiv.groups {\n  border: 1px solid #ccc;\n  background-color: #f1f1f1;\n  margin-bottom: 15px;\n}\n\ndiv.command {\nmargin-top: 15px;\n}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/html/static/snippets.js",
    "content": "var snippets=document.querySelectorAll('.snippet');[].forEach.call(snippets,function(snippet){snippet.firstChild.insertAdjacentHTML('beforebegin','<button class=\"btn\" data-clipboard-snippet><img class=\"clippy\" width=\"13\" src=\"assets/images/clippy.svg\" alt=\"Copy to clipboard\"></button>');});var clipboardSnippets=new ClipboardJS('[data-clipboard-snippet]',{target:function(trigger){return trigger.nextElementSibling;}});clipboardSnippets.on('success',function(e){e.clearSelection();showTooltip(e.trigger,'Copied!');});clipboardSnippets.on('error',function(e){showTooltip(e.trigger,fallbackMessage(e.action));});\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/html/static/styles.css",
    "content": ".theme-body {\n  background-color: #efefef;\n  color: #333;\n  font-family: 'Source Sans Pro', Helvetica, sans-serif;\n}\n\n.theme-navbar {\n  background-color: #fff;\n  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);\n  color: #333;\n  font-size: 13px;\n  font-weight: 100;\n  height: 46px;\n  overflow: hidden;\n  padding: 0 10px;\n}\n\n.theme-navbar__logo-wrap {\n  display: inline-block;\n  height: 100%;\n  overflow: hidden;\n  padding: 10px 15px;\n  width: 300px;\n}\n\n.theme-navbar__logo {\n  height: 100%;\n  max-height: 25px;\n}\n\n.theme-heading {\n  font-size: 20px;\n  font-weight: 500;\n  margin-bottom: 10px;\n  margin-top: 0;\n}\n\n.theme-panel {\n  background-color: #fff;\n  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  padding: 30px;\n}\n\n.theme-btn-provider {\n  background-color: #fff;\n  color: #333;\n  min-width: 350px;\n}\n\n.theme-btn-provider:hover {\n  color: #999;\n}\n\n.theme-btn--primary {\n  background-color: #333;\n  border: none;\n  color: #fff;\n  min-width: 200px;\n  padding: 6px 12px;\n}\n\n.theme-btn--primary:hover {\n  background-color: #666;\n  color: #fff;\n}\n\n.theme-btn--success {\n  background-color: #2FC98E;\n  color: #fff;\n  width: 350px;\n}\n\n.theme-btn--success:hover {\n  background-color: #49E3A8;\n}\n\n.theme-form-row {\n  display: block;\n  margin: 20px auto;\n}\n\n.theme-form-input:focus,\n.theme-form-input:active {\n  border-color: #66AFE9;\n  outline: none;\n}\n\n.theme-form-label {\n  font-size: 13px;\n  font-weight: 600;\n  margin: 4px auto;\n  position: relative;\n  text-align: left;\n  width: 350px;\n}\n\n.theme-form-description {\n  font-size: 13px;\n  font-weight: 300;\n  margin: 4px auto;\n  position: relative;\n  text-align: left;\n  width: 350px;\n}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/html/static/tabs.css",
    "content": " /* Style the tab */\n .tab {\n  overflow: hidden;\n  border: 1px solid #ccc;\n  background-color: #f1f1f1;\n}\n\n/* Style the buttons inside the tab */\n.tab button {\n  background-color: inherit;\n  float: left;\n  border: none;\n  outline: none;\n  cursor: pointer;\n  padding: 14px 16px;\n  transition: 0.3s;\n  font-size: 17px;\n}\n\n/* Change background color of buttons on hover */\n.tab button:hover {\n  background-color: #ddd;\n}\n\n/* Create an active/current tablink class */\n.tab button.active {\n  background-color: #ccc;\n}\n\n/* Style the tab content */\n.tabcontent {\n  display: none;\n  padding: 6px 12px;\n  border: 1px solid #ccc;\n  border-top: none;\n}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/html/static/tooltips.js",
    "content": "var btns=document.querySelectorAll('.btn');for(var i=0;i<btns.length;i++){btns[i].addEventListener('mouseleave',clearTooltip);btns[i].addEventListener('blur',clearTooltip);}\nfunction clearTooltip(e){e.currentTarget.setAttribute('class','btn');e.currentTarget.removeAttribute('aria-label');}\nfunction showTooltip(elem,msg){elem.setAttribute('class','btn tooltipped tooltipped-s');elem.setAttribute('aria-label',msg);}\nfunction fallbackMessage(action){var actionMsg='';var actionKey=(action==='cut'?'X':'C');if(/iPhone|iPad/i.test(navigator.userAgent)){actionMsg='No support :(';}\nelse if(/Mac/i.test(navigator.userAgent)){actionMsg='Press ⌘-'+actionKey+' to '+action;}\nelse{actionMsg='Press Ctrl-'+actionKey+' to '+action;}\nreturn actionMsg;}\nhljs.initHighlightingOnLoad();\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/main.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\n\toidc \"github.com/coreos/go-oidc/v3/oidc\"\n\t\"github.com/spf13/cast\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\nvar (\n\tconfig_file string\n\tdebug       bool\n)\n\ntype debugTransport struct {\n\tt http.RoundTripper\n}\n\nfunc (d debugTransport) RoundTrip(req *http.Request) (*http.Response, error) {\n\treqDump, err := httputil.DumpRequest(req, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tlog.Printf(\"%s\", reqDump)\n\n\tresp, err := d.t.RoundTrip(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trespDump, err := httputil.DumpResponse(resp, true)\n\tif err != nil {\n\t\tresp.Body.Close()\n\t\treturn nil, err\n\t}\n\tlog.Printf(\"%s\", respDump)\n\treturn resp, nil\n}\n\n// Define each cluster\ntype Cluster struct {\n\tName                      string\n\tNamespace                 string\n\tShort_Description         string\n\tDescription               string\n\tIssuer                    string\n\tClient_Secret             string\n\tClient_ID                 string\n\tConnector_ID              string\n\tK8s_Master_URI            string\n\tK8s_Ca_URI                string\n\tK8s_Ca_Pem                string\n\tK8s_Ca_Pem_File           string\n\tK8s_Ca_Pem_Base64_Encoded string\n\tStatic_Context_Name       bool\n\tScopes                    []string\n\n\tVerifier       *oidc.IDTokenVerifier\n\tProvider       *oidc.Provider\n\tOfflineAsScope bool\n\tClient         *http.Client\n\tRedirect_URI   string\n\tConfig         Config\n}\n\n// Define our configuration\ntype Config struct {\n\tClusters             []Cluster\n\tListen               string\n\tWeb_Path_Prefix      string\n\tTLS_Cert             string\n\tTLS_Key              string\n\tIDP_Ca_URI           string\n\tIDP_Ca_Pem           string\n\tIDP_Ca_Pem_File      string\n\tLogo_Uri             string\n\tStatic_Context_Name  bool\n\tTrusted_Root_Ca      []string\n\tTrusted_Root_Ca_File string\n\tKubectl_Version      string\n}\n\nfunc substituteEnvVars(text string) string {\n\tre := regexp.MustCompile(`\\${([a-zA-Z0-9\\-_]+)}`)\n\tmatches := re.FindAllStringSubmatch(text, -1)\n\tfor _, val := range matches {\n\t\tenvVar := os.Getenv(val[1])\n\t\ttext = strings.Replace(text, val[0], envVar, -1)\n\t}\n\treturn text\n}\n\n// Start the app\n// Do some config parsing\n// Setup http-clients and oidc providers\n// Define per-cluster handlers\nfunc start_app(config Config) {\n\n\t// Config validation\n\tlistenURL, err := url.Parse(config.Listen)\n\tif err != nil {\n\t\tlog.Fatalf(\"parse listen address: %v\", err)\n\t}\n\n\tvar s struct {\n\t\tScopesSupported []string `json:\"scopes_supported\"`\n\t}\n\n\tcertp, err := x509.SystemCertPool()\n\tif err != nil {\n\t\tlog.Fatalf(\"error reading the system cert pool: %v\", err)\n\t}\n\t// Load Inline CA certs\n\tif len(config.Trusted_Root_Ca) > 0 {\n\t\tfor _, cert := range config.Trusted_Root_Ca {\n\t\t\tok := certp.AppendCertsFromPEM([]byte(cert))\n\t\t\tif !ok {\n\t\t\t\tlog.Fatalf(\"Failed to parse a trusted cert, pem format expected\")\n\t\t\t}\n\t\t}\n\t}\n\t// Load CA certs from file\n\tif config.Trusted_Root_Ca_File != \"\" {\n\t\tcontent, err := os.ReadFile(config.Trusted_Root_Ca_File)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Failed to read file Trusted Root CA %s, %v\", config.Trusted_Root_Ca_File, err)\n\t\t}\n\t\tok := certp.AppendCertsFromPEM([]byte(content))\n\t\tif !ok {\n\t\t\tlog.Fatalf(\"Failed to parse a trusted cert from file %s, pem format expected\", config.Trusted_Root_Ca_File)\n\t\t}\n\t}\n\n\tmTlsConfig := &tls.Config{\n\t\tMinVersion: tls.VersionTLS12, // minimum TLS 1.2\n\t\t// P curve order does not matter, as breaking one means all others can be brute-forced as well:\n\t\t// Golang developers prefer:\n\t\tCurvePreferences:         []tls.CurveID{tls.X25519, tls.CurveP256, tls.CurveP384, tls.CurveP521},\n\t\tPreferServerCipherSuites: true, // Server chooses ciphersuite, order matters below:\n\t\tCipherSuites: []uint16{\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n\t\t\ttls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n\t\t\ttls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n\t\t\ttls.TLS_CHACHA20_POLY1305_SHA256, // TLS 1.3\n\t\t\ttls.TLS_AES_256_GCM_SHA384,       // TLS 1.3\n\t\t\ttls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n\t\t\ttls.TLS_AES_128_GCM_SHA256, // TLS 1.3\n\t\t},\n\t\tRootCAs: certp,\n\t}\n\n\ttr := &http.Transport{\n\t\tTLSClientConfig: mTlsConfig,\n\n\t\t// Set proxy callback for proxy support in this transport\n\t\tProxy: http.ProxyFromEnvironment,\n\t}\n\n\t// Ensure trailing slash on web-path-prefix\n\tweb_path_prefix := config.Web_Path_Prefix\n\tif web_path_prefix != \"/\" {\n\t\tweb_path_prefix = fmt.Sprintf(\"%s/\", path.Clean(web_path_prefix))\n\t\tconfig.Web_Path_Prefix = web_path_prefix\n\t}\n\n\t// Generate handlers for each cluster\n\tfor i := range config.Clusters {\n\t\tcluster := config.Clusters[i]\n\t\tif debug {\n\t\t\tif cluster.Client == nil {\n\t\t\t\tcluster.Client = &http.Client{\n\t\t\t\t\tTransport: debugTransport{tr},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcluster.Client.Transport = debugTransport{tr}\n\t\t\t}\n\t\t} else {\n\t\t\tcluster.Client = &http.Client{Transport: tr}\n\t\t}\n\n\t\tctx := oidc.ClientContext(context.Background(), cluster.Client)\n\t\tlog.Printf(\"Creating new provider %s\", cluster.Issuer)\n\t\tprovider, err := oidc.NewProvider(ctx, cluster.Issuer)\n\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Failed to query provider %q: %v\\n\", cluster.Issuer, err)\n\t\t}\n\n\t\tcluster.Provider = provider\n\n\t\tlog.Printf(\"Verifying client %s\", cluster.Client_ID)\n\n\t\tverifier := provider.Verifier(&oidc.Config{ClientID: cluster.Client_ID})\n\n\t\tcluster.Verifier = verifier\n\n\t\tif err := provider.Claims(&s); err != nil {\n\t\t\tlog.Fatalf(\"Failed to parse provider scopes_supported: %v\", err)\n\t\t}\n\n\t\tif len(s.ScopesSupported) == 0 {\n\t\t\t// scopes_supported is a \"RECOMMENDED\" discovery claim, not a required\n\t\t\t// one. If missing, assume that the provider follows the spec and has\n\t\t\t// an \"offline_access\" scope.\n\t\t\tcluster.OfflineAsScope = true\n\t\t} else {\n\t\t\t// See if scopes_supported has the \"offline_access\" scope.\n\t\t\tcluster.OfflineAsScope = func() bool {\n\t\t\t\tfor _, scope := range s.ScopesSupported {\n\t\t\t\t\tif scope == oidc.ScopeOfflineAccess {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}()\n\t\t}\n\n\t\tif len(cluster.Scopes) == 0 {\n\t\t\tcluster.Scopes = []string{\"openid\", \"profile\", \"email\", \"offline_access\", \"groups\"}\n\t\t}\n\n\t\tif cluster.K8s_Ca_Pem_File != \"\" {\n\t\t\tcontent, err := os.ReadFile(cluster.K8s_Ca_Pem_File)\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"Failed to load CA from file %s, %s\", cluster.K8s_Ca_Pem_File, err)\n\t\t\t}\n\t\t\tcluster.K8s_Ca_Pem = cast.ToString(content)\n\t\t}\n\n\t\tif cluster.K8s_Ca_Pem == \"\" && cluster.K8s_Ca_Pem_Base64_Encoded != \"\" {\n\t\t\tp, err := base64.StdEncoding.DecodeString(cluster.K8s_Ca_Pem_Base64_Encoded)\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"Failed to base64 decode ca pem: %s\", err.Error())\n\t\t\t}\n\n\t\t\tcluster.K8s_Ca_Pem = string(p)\n\t\t}\n\n\t\tcluster.Config = config\n\n\t\tbase_redirect_uri, err := url.Parse(cluster.Redirect_URI)\n\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Parsing redirect_uri address: %v\", err)\n\t\t}\n\n\t\t// Each cluster gets a different login and callback URL\n\t\thttp.HandleFunc(base_redirect_uri.Path, cluster.handleCallback)\n\t\tlog.Printf(\"Registered callback handler at: %s\", base_redirect_uri.Path)\n\n\t\tlogin_uri := path.Join(config.Web_Path_Prefix, \"login\", cluster.Name)\n\t\thttp.HandleFunc(login_uri, cluster.handleLogin)\n\t\tlog.Printf(\"Registered login handler at: %s\", login_uri)\n\t}\n\n\t// Index page\n\thttp.HandleFunc(config.Web_Path_Prefix, config.handleIndex)\n\n\t// Serve static html assets\n\tfs := http.FileServer(http.Dir(\"html/static/\"))\n\tstatic_uri := path.Join(config.Web_Path_Prefix, \"static\") + \"/\"\n\tlog.Printf(\"Registered static assets handler at: %s\", static_uri)\n\n\thttp.Handle(static_uri, http.StripPrefix(static_uri, fs))\n\n\t// Determine whether to use TLS or not\n\tswitch listenURL.Scheme {\n\tcase \"http\":\n\t\tlog.Printf(\"Listening on %s\", config.Listen)\n\t\terr := http.ListenAndServe(listenURL.Host, nil)\n\t\tlog.Fatal(err)\n\tcase \"https\":\n\t\tlog.Printf(\"Listening on %s\", config.Listen)\n\t\terr := http.ListenAndServeTLS(listenURL.Host, config.TLS_Cert, config.TLS_Key, nil)\n\t\tlog.Fatal(err)\n\n\tdefault:\n\t\tlog.Fatalf(\"Listen address %q is not using http or https\", config.Listen)\n\t}\n}\n\nfunc substituteEnvVarsRecursive(copy, original reflect.Value) {\n\tswitch original.Kind() {\n\n\tcase reflect.Ptr:\n\t\toriginalValue := original.Elem()\n\t\tif !originalValue.IsValid() {\n\t\t\treturn\n\t\t}\n\t\tcopy.Set(reflect.New(originalValue.Type()))\n\t\tsubstituteEnvVarsRecursive(copy.Elem(), originalValue)\n\n\tcase reflect.Interface:\n\t\toriginalValue := original.Elem()\n\t\tcopyValue := reflect.New(originalValue.Type()).Elem()\n\t\tsubstituteEnvVarsRecursive(copyValue, originalValue)\n\t\tcopy.Set(copyValue)\n\n\tcase reflect.Struct:\n\t\tfor i := 0; i < original.NumField(); i += 1 {\n\t\t\tsubstituteEnvVarsRecursive(copy.Field(i), original.Field(i))\n\t\t}\n\n\tcase reflect.Slice:\n\t\tcopy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap()))\n\t\tfor i := 0; i < original.Len(); i += 1 {\n\t\t\tsubstituteEnvVarsRecursive(copy.Index(i), original.Index(i))\n\t\t}\n\n\tcase reflect.Map:\n\t\tcopy.Set(reflect.MakeMap(original.Type()))\n\t\tfor _, key := range original.MapKeys() {\n\t\t\toriginalValue := original.MapIndex(key)\n\t\t\tcopyValue := reflect.New(originalValue.Type()).Elem()\n\t\t\tsubstituteEnvVarsRecursive(copyValue, originalValue)\n\t\t\tcopy.SetMapIndex(key, copyValue)\n\t\t}\n\n\tcase reflect.String:\n\t\treplacedString := substituteEnvVars(original.Interface().(string))\n\t\tcopy.SetString(replacedString)\n\n\tdefault:\n\t\tcopy.Set(original)\n\t}\n\n}\n\nvar RootCmd = &cobra.Command{\n\tUse:   \"dex-k8s-authenticator\",\n\tShort: \"Dex Kubernetes Authenticator\",\n\tLong:  `Dex Kubernetes Authenticator provides a web-interface to generate a kubeconfig file based on a selected Kubernetes cluster. One or more clusters can be defined in the configuration file.`,\n\tRun: func(cmd *cobra.Command, args []string) {\n\n\t\tvar config Config\n\t\terr := viper.Unmarshal(&config)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Unable to decode configuration into struct, %v\", err)\n\t\t}\n\n\t\toriginal := reflect.ValueOf(config)\n\t\tcopy := reflect.New(original.Type()).Elem()\n\t\tsubstituteEnvVarsRecursive(copy, original)\n\n\t\t// Start the app\n\t\tstart_app(copy.Interface().(Config))\n\n\t\t// Fallback if no args specified\n\t\tcmd.HelpFunc()(cmd, args)\n\n\t},\n}\n\n// Read in config file\nfunc initConfig() {\n\n\tif config_file != \"\" {\n\t\t//viper.SetConfigFile(config_file)\n\t\t// get the filepath\n\t\tabs, err := filepath.Abs(config_file)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Error reading config file, %s\", err)\n\t\t}\n\n\t\t// get the config name\n\t\tbase := filepath.Base(abs)\n\n\t\t// get the path\n\t\tpath := filepath.Dir(abs)\n\n\t\tviper.SetConfigName(strings.Split(base, \".\")[0])\n\t\tviper.AddConfigPath(path)\n\t\tviper.SetDefault(\"web_path_prefix\", \"/\")\n\n\t\tconfig, err := os.ReadFile(config_file)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Error reading config file, %s\", err)\n\t\t}\n\n\t\torigConfigStr := bytes.NewBuffer(config).String()\n\n\t\tif err := viper.ReadConfig(bytes.NewBufferString(origConfigStr)); err != nil {\n\t\t\tlog.Fatalf(\"viper.ReadConfig failed to read config, %s\", err.Error())\n\t\t}\n\n\t\tlog.Printf(\"Using config file: %s\", viper.ConfigFileUsed())\n\t}\n}\n\n// Initialization\nfunc init() {\n\tcobra.OnInitialize(initConfig)\n\n\tif err := viper.BindPFlags(RootCmd.Flags()); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tRootCmd.Flags().StringVar(&config_file, \"config\", \"\", \"./config.yml\")\n\tRootCmd.PersistentFlags().BoolVarP(&debug, \"debug\", \"d\", false, \"Enable debug logging\")\n}\n\n// Let's go!\nfunc main() {\n\tif err := RootCmd.Execute(); err != nil {\n\t\tfmt.Println(err)\n\t\tos.Exit(-1)\n\t}\n}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/error.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"google\" content=\"notranslate\">\n    <meta http-equiv=\"Content-Language\" content=\"en\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n\n    <title>Error - {{ .Code }}</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <link href=\"{{ .Web_Path_Prefix }}static/main.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link href=\"{{ .Web_Path_Prefix }}static/styles.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link rel=\"icon\" href=\"{{ .Web_Path_Prefix }}static/favicon.png\">\n  </head>\n\n  <body class=\"theme-body\">\n    <div class=\"theme-navbar\">\n      {{ if .Logo_Uri }}\n      <div class=\"theme-navbar__logo-wrap\">\n          <img class=\"theme-navbar__logo\" src=\"{{ .Logo_Uri }}\"/>\n      </div>\n      {{ end }}\n    </div>\n\n    <div class=\"dex-kubeconfig-container\">\n\n      <div class=\"theme-panel\">\n        <h2 class=\"theme-heading\">Error - {{ .Code }}</h2>\n        {{ if .Error_Description }}\n        <p>An error has ocurred with the following details:</p>\n        <p>\n            {{ .Error_Description }}\n        </p>\n        {{ end }}\n      </div>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/id-token-tab.html",
    "content": "{{ define \"id-token-content\" }}\n\n<p>The ID Token signed by dex and returned as part of the OAuth2 response - represented as a Json Web Token (JWT).</p>\n\n<div class=\"command\">\n  <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n    <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n  </button>\n  <pre><code>{{ .IDToken }}</pre></code>\n</div>\n{{ end }}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"google\" content=\"notranslate\">\n    <meta http-equiv=\"Content-Language\" content=\"en\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n\n    <title>Generate Kubernetes Token</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <link href=\"{{ .Web_Path_Prefix }}static/main.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link href=\"{{ .Web_Path_Prefix }}static/styles.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link rel=\"icon\" href=\"{{ .Web_Path_Prefix }}static/favicon.png\">\n  </head>\n\n  <body class=\"theme-body\">\n    <div class=\"theme-navbar\">\n      {{ if .Logo_Uri }}\n      <div class=\"theme-navbar__logo-wrap\">\n          <img class=\"theme-navbar__logo\" src=\"{{ .Logo_Uri }}\"/>\n      </div>\n      {{ end }}\n    </div>\n\n    <div class=\"dex-container\">\n\n      <div class=\"theme-panel\">\n        <h2 class=\"theme-heading\">Generate Kubernetes Token</h2>\n        <div>\n            <p>\n              Select which cluster you require a token for:\n            </p>\n\n            {{ range $cluster := .Clusters }}\n\n            <div class=\"theme-form-row\">\n                <p class=\"theme-form-description\">{{$cluster.Description}}</p>\n                <a href=\"{{ $.Web_Path_Prefix }}login/{{$cluster.Name}}\" target=\"_self\">\n                  <button class=\"dex-btn theme-btn-provider\">\n                    <span class=\"dex-btn-icon dex-btn-icon--local\"></span>\n                    <span class=\"dex-btn-text\">{{$cluster.Short_Description}}</span>\n                  </button>\n                </a>\n              </div>\n              {{ end }}\n            </div>\n        </div>\n      </div>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/kubeconfig.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"google\" content=\"notranslate\">\n    <meta http-equiv=\"Content-Language\" content=\"en\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n\n    <title>Kubernetes Configuration</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <link href=\"{{ .Web_Path_Prefix }}static/main.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link href=\"{{ .Web_Path_Prefix }}static/styles.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link href=\"{{ .Web_Path_Prefix }}static/tabs.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link rel=\"icon\" href=\"{{ .Web_Path_Prefix }}static/favicon.png\">\n  </head>\n\n<body class=\"theme-body\">\n  <div class=\"theme-navbar\">\n    {{ if .LogoURI }}\n    <div class=\"theme-navbar__logo-wrap\">\n        <img class=\"theme-navbar__logo\" src=\"{{ .LogoURI }}\"/>\n    </div>\n    {{ end }}\n  </div>\n\n  <div class=\"dex-kubeconfig-container\">\n    <div class=\"theme-panel\">\n      <div style=\"float:right\">\n        <a href=\"{{ .Web_Path_Prefix }}\">Login Again</a>\n      </div>\n      <h2 class=\"theme-heading\">Generated Kubernetes Token - {{ .ShortDescription }}</h2>\n\n      <div>\n\n        <p>Please check that you have been assigned to the expected Groups, then follow the instructions\n          based on your OS.\n        </p>\n\n        <div class=\"groups\">\n        <pre><code>{{ .Claims }}</code></pre>\n        </div>\n\n        <div class=\"tab\">\n          <button class=\"tablinks active\" onclick=\"openTab(event, 'Linux')\">Linux</button>\n          <button class=\"tablinks\" onclick=\"openTab(event, 'MacOS')\">MacOS</button>\n          <button class=\"tablinks\" onclick=\"openTab(event, 'Windows')\">Windows</button>\n          <button class=\"tablinks\" onclick=\"openTab(event, 'IDToken')\">ID Token</button>\n        </div>\n\n        <div id=\"Linux\" class=\"tabcontent\" style=\"display: block\">\n          {{ template \"linux-tab-content\" . }}\n        </div>\n\n        <div id=\"MacOS\" class=\"tabcontent\">\n          {{ template \"mac-tab-content\" . }}\n        </div>\n\n        <div id=\"Windows\" class=\"tabcontent\">\n          {{ template \"windows-tab-content\" . }}\n        </div>\n\n        <div id=\"IDToken\" class=\"tabcontent\">\n          {{ template \"id-token-content\" . }}\n        </div>\n\n    </div>\n  </div>\n\n  <script src=\"{{ .Web_Path_Prefix }}static/highlight.pack.min.js\"></script>\n  <script src=\"{{ .Web_Path_Prefix }}static/clipboard.min.js\"></script>\n  <script src=\"{{ .Web_Path_Prefix }}static/snippets.js\"></script>\n  <script src=\"{{ .Web_Path_Prefix }}static/tooltips.js\"></script>\n  <script>\n      var clipboard = new ClipboardJS('.btn');\n      clipboard.on('success', function(e) {\n          console.log(e);\n      });\n      clipboard.on('error', function(e) {\n          console.log(e);\n      });\n  </script>\n\n  <script>\n      function openTab(evt, tabName) {\n          var i, tabcontent, tablinks;\n          tabcontent = document.getElementsByClassName(\"tabcontent\");\n          for (i = 0; i < tabcontent.length; i++) {\n              tabcontent[i].style.display = \"none\";\n          }\n          tablinks = document.getElementsByClassName(\"tablinks\");\n          for (i = 0; i < tablinks.length; i++) {\n              tablinks[i].className = tablinks[i].className.replace(\" active\", \"\");\n          }\n          document.getElementById(tabName).style.display = \"block\";\n          evt.currentTarget.className += \" active\";\n      }\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/linux-mac-common.html",
    "content": "{{ define \"linux-mac-common\" }}\n  {{ if .IDPCaURI }}\n    <h3>Copy IDP CA Certificate From URL</h3>\n\n    <p>Copy this CA Certificate and download it to your .kube directory</p>\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n      <pre><code>curl --create-dirs -s {{ .IDPCaURI }} -o ${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt</code></pre>\n    </div>\n  {{ end }}\n\n  {{ if .IDPCaPem }}\n    <h3>Copy IDP CA Certificate From PEM</h3>\n\n    <p>Put the CA Certificate into your .kube directory</p>\n\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n      <pre><code>mkdir -p ${HOME}/.kube/certs/{{ .ClusterName }}/ &amp;&amp; cat &lt;&lt; EOF &gt; ${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt\n{{ .IDPCaPem }}\nEOF</code></pre>\n    </div>\n  {{ end }}\n\n\n  {{ if .K8sCaURI }}\n    <h3>Copy Kubernetes CA Certificate From URL</h3>\n\n    <p>Copy this CA Certificate and download it to your .kube directory</p>\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float: right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n      <pre><code>curl --create-dirs -s {{ .K8sCaURI }} -o ${HOME}/.kube/certs/{{ .ClusterName }}/k8s-ca.crt</code></pre>\n    </div>\n  {{ end }}\n\n  {{ if .K8sCaPem }}\n    <h3>Copy Kubernetes CA Certificate From PEM</h3>\n\n    <p>Put the CA Certificate into your .kube directory</p>\n\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n      <pre><code>mkdir -p ${HOME}/.kube/certs/{{ .ClusterName }}/ &amp;&amp; cat &lt;&lt; EOF &gt; ${HOME}/.kube/certs/{{ .ClusterName }}/k8s-ca.crt\n{{ .K8sCaPem }}\nEOF</code></pre>\n    </div>\n  {{ end }}\n\n  <h3>Run configuration commands</h3>\n\n  <p>These commands will update <tt>~/.kube/config</tt></p>\n\n  <div class=\"command\">\n\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\">\n    </button>\n  <pre><code>kubectl config set-cluster {{ .ClusterName }} \\\n  {{- if or .K8sCaPem .K8sCaURI }}\n    --certificate-authority=${HOME}/.kube/certs/{{ .ClusterName}}/k8s-ca.crt \\\n  {{- end }}\n    --server={{ .K8sMasterURI }}</code></pre>\n  </div>\n\n  <div class=\"command\">\n\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n    </button>\n  <pre><code>kubectl config set-credentials {{ .Username }}-{{ .ClusterName }} \\\n    --auth-provider=oidc \\\n    --auth-provider-arg=\"idp-issuer-url={{ .Issuer }}\" \\\n    --auth-provider-arg=\"client-id={{ .ClientID }}\" \\\n    --auth-provider-arg=\"client-secret={{ .ClientSecret }}\" \\\n    --auth-provider-arg=\"refresh-token={{ .RefreshToken }}\" \\\n    --auth-provider-arg=\"id-token={{ .IDToken }}\"\n  {{- if or (.IDPCaURI) (.IDPCaPem) }} \\\n    --auth-provider-arg=idp-certificate-authority=${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt\n  {{- end }}</code></pre>\n  </div>\n\n  <div class=\"command\">\n\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\">\n    </button>\n    <pre><code class=\"hljs\">kubectl config set-context {{ if not .StaticContextName }}{{ .Username }}-{{ end }}{{ .ClusterName }} \\\n    --cluster={{ .ClusterName }}{{ if .Namespace }} --namespace={{ .Namespace }}{{ end }} \\\n    --user={{ .Username}}-{{.ClusterName }}</code></pre>\n  </div>\n\n  <div class=\"command\">\n\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n    </button>\n    <pre><code class=\"hljs\">kubectl config use-context {{ if not .StaticContextName }}{{ .Username }}-{{ end }}{{ .ClusterName}}</code></pre>\n  </div>\n\n{{ end }}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/linux-tab.html",
    "content": "{{ define \"linux-tab-content\" }}\n  <h3>Install and Set Up kubectl</h3>\n  <div>\n  See\n  <a title=\"Install and setup kubectl\" href=\"https://kubernetes.io/docs/tasks/tools/install-kubectl/\">\n    https://kubernetes.io/docs/tasks/tools/install-kubectl\n  </a>\n  {{ if .KubectlVersion }}\n  <p>\n  Download kubectl:\n  <a title=\"Download kubectl\" href=\"https://storage.googleapis.com/kubernetes-release/release/{{.KubectlVersion}}/bin/linux/amd64/kubectl\">\n    https://storage.googleapis.com/kubernetes-release/release/{{.KubectlVersion}}/bin/linux/amd64/kubectl\n  </a>\n  </p>\n  {{ end }}\n  </div>\n  {{ template \"linux-mac-common\" . }}\n{{ end }}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/mac-tab.html",
    "content": "{{ define \"mac-tab-content\" }}\n  <h3>Install and Set Up kubectl</h3>\n  <div>\n  See\n  <a title=\"Install and setup kubectl\" href=\"https://kubernetes.io/docs/tasks/tools/install-kubectl/\">\n    https://kubernetes.io/docs/tasks/tools/install-kubectl\n  </a>\n  {{ if .KubectlVersion }}\n  <p>\n  Download kubectl:\n  <a title=\"Download kubectl\" href=\"https://storage.googleapis.com/kubernetes-release/release/{{.KubectlVersion}}/bin/darwin/amd64/kubectl\">\n    https://storage.googleapis.com/kubernetes-release/release/{{.KubectlVersion}}/bin/darwin/amd64/kubectl\n  </a>\n  </p>\n  {{ end }}\n  </div>\n  {{ template \"linux-mac-common\" . }}\n{{ end }}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates/windows-tab.html",
    "content": "{{ define \"windows-tab-content\" }}\n<h3>Install and Set Up kubectl</h3>\n    <div>\n    See\n    <a title=\"Install and setup kubectl\" href=\"https://kubernetes.io/docs/tasks/tools/install-kubectl/\">\n      https://kubernetes.io/docs/tasks/tools/install-kubectl\n    </a>\n\n    {{ if .KubectlVersion }}\n    <p>\n    Download kubectl:\n    <a title=\"Download kubectl\" href=\"https://storage.googleapis.com/kubernetes-release/release/{{.KubectlVersion}}/bin/windows/amd64/kubectl.exe\">\n      https://storage.googleapis.com/kubernetes-release/release/{{.KubectlVersion}}/bin/windows/amd64/kubectl.exe\n    </a>\n    </p>\n    {{ end }}\n  </div>\n\n  {{ if .IDPCaURI }}\n    <h3>Copy IDP CA Certificate From URL</h3>\n\n    <p>Copy this CA Certificate and download it to your .kube directory</p>\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n\n      <pre><code>curl --create-dirs -s {{ .IDPCaURI }} -o ${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt</code></pre>\n    </div>\n  {{ end }}\n\n  {{ if .IDPCaPem }}\n    <h3>Copy IDP CA From Pem</h3>\n\n    <p>Put the CA Certificate into your .kube directory</p>\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n\n      <pre><code>mkdir -p ${HOME}/.kube/certs/{{ .ClusterName }}/ &amp;&amp; cat &lt;&lt; EOF &gt; ${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt\n{{ .IDPCaPem}}\nEOF</code></pre>\n    </div>\n  {{ end }}\n\n\n  {{ if .K8sCaURI }}\n    <h3>Copy Kubernetes CA Certificate From URL</h3>\n\n    <p>Copy this CA Certificate and download it to your .kube directory</p>\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float: right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n      <pre><code>curl --create-dirs -s {{ .K8sCaURI }} -o ${HOME}/.kube/certs/{{ .ClusterName }}/k8s-ca.crt</code></pre>\n    </div>\n  {{ end }}\n\n  {{ if .K8sCaPem }}\n    <h3>Copy Kubernetes CA Certificate From PEM</h3>\n\n    <p>Put the CA Certificate into your .kube directory</p>\n\n    <div class=\"command\">\n\n      <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n        <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n      </button>\n      <pre><code>mkdir -p ${HOME}/.kube/certs/{{ .ClusterName }}/ &amp;&amp; cat &lt;&lt; EOF &gt; ${HOME}/.kube/certs/{{ .ClusterName }}/k8s-ca.crt\n{{ .K8sCaPem }}\nEOF</code></pre>\n    </div>\n  {{ end }}\n\n  <h3>Run configuration commands</h3>\n\n  <p>These commands will update <tt>~/.kube/config</tt></p>\n\n  <div class=\"command\">\n\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\">\n    </button>\n  <pre><code>kubectl config set-cluster {{ .ClusterName }}\n    {{- if or .K8sCaPem .K8sCaURI }} --certificate-authority=${HOME}/.kube/certs/{{ .ClusterName}}/k8s-ca.crt\n    {{- end }} --server={{ .K8sMasterURI }}</code></pre>\n  </div>\n\n  <div class=\"command\">\n\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n    </button>\n  <pre><code>kubectl config set-credentials {{ .Username }}-{{ .ClusterName }} --auth-provider=oidc --auth-provider-arg=idp-issuer-url={{ .Issuer }} --auth-provider-arg=client-id={{ .ClientID }} --auth-provider-arg=client-secret={{ .ClientSecret }} --auth-provider-arg=refresh-token={{ .RefreshToken }} --auth-provider-arg=id-token={{ .IDToken }}\n  {{- if or (.IDPCaURI) (.IDPCaPem) }} --auth-provider-arg=idp-certificate-authority=${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt\n  {{- end }}</code></pre>\n  </div>\n  <div class=\"command\">\n\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\">\n    </button>\n    <pre><code class=\"hljs\">kubectl config set-context {{ if not .StaticContextName }}{{ .Username }}-{{ end }}{{ .ClusterName }} --cluster={{ .ClusterName }} --user={{ .Username}}-{{.ClusterName }}</code></pre>\n  </div>\n\n  <div class=\"command\">\n    <button class=\"btn\" style=\"float:right\" data-clipboard-snippet=\"\">\n      <img class=\"clippy\" width=\"13\" src=\"{{ .Web_Path_Prefix }}static/clippy.svg\" alt=\"\"/>\n    </button>\n    <pre><code class=\"hljs\">kubectl config use-context {{ if not .StaticContextName }}{{ .Username }}-{{ end }}{{ .ClusterName}}</code></pre>\n  </div>\n\n{{ end }}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/app/resources/templates.go",
    "content": "// FIXME: Dislike this file a bit - what's the take on referencing\n// viper config values (treat it as a global, or pass values around?)\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"log\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// compile all templates and cache them\nvar templates = template.Must(template.ParseGlob(\"./templates/*.html\"))\n\nfunc renderIndex(w http.ResponseWriter, config *Config) {\n\tt, _ := template.ParseFiles(\"./templates/index.html\")\n\terr := t.Execute(w, config)\n\tif err != nil {\n\t\tlog.Println(err)\n\t\thttp.Error(w, http.StatusText(500), 500)\n\t}\n}\n\ntype templateData struct {\n\tIDToken           string\n\tRefreshToken      string\n\tRedirectURL       string\n\tClaims            string\n\tUsername          string\n\tIssuer            string\n\tClusterName       string\n\tShortDescription  string\n\tClientSecret      string\n\tClientID          string\n\tK8sMasterURI      string\n\tK8sCaURI          string\n\tK8sCaPem          string\n\tIDPCaURI          string\n\tIDPCaPem          string\n\tLogoURI           string\n\tWeb_Path_Prefix   string\n\tStaticContextName bool\n\tKubectlVersion    string\n\tNamespace         string\n}\n\nfunc (cluster *Cluster) renderToken(w http.ResponseWriter,\n\tidToken,\n\trefreshToken string,\n\tidpCaURI string,\n\tidpCaPem string,\n\tlogoURI string,\n\twebPathPrefix string,\n\tkubectlVersion string,\n\tclaims []byte) {\n\n\tvar data map[string]interface{}\n\terr := json.Unmarshal(claims, &data)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tunix_username := \"user\"\n\tif data[\"email\"] != nil {\n\t\temail := data[\"email\"].(string)\n\t\tunix_username = strings.Split(email, \"@\")[0]\n\t}\n\n\ttoken_data := templateData{\n\t\tIDToken:           idToken,\n\t\tRefreshToken:      refreshToken,\n\t\tRedirectURL:       cluster.Redirect_URI,\n\t\tClaims:            string(claims),\n\t\tUsername:          unix_username,\n\t\tIssuer:            data[\"iss\"].(string),\n\t\tClusterName:       cluster.Name,\n\t\tShortDescription:  cluster.Short_Description,\n\t\tClientSecret:      cluster.Client_Secret,\n\t\tClientID:          cluster.Client_ID,\n\t\tK8sMasterURI:      cluster.K8s_Master_URI,\n\t\tK8sCaURI:          cluster.K8s_Ca_URI,\n\t\tK8sCaPem:          cluster.K8s_Ca_Pem,\n\t\tIDPCaURI:          idpCaURI,\n\t\tIDPCaPem:          idpCaPem,\n\t\tLogoURI:           logoURI,\n\t\tWeb_Path_Prefix:   webPathPrefix,\n\t\tStaticContextName: cluster.Static_Context_Name,\n\t\tNamespace:         cluster.Namespace,\n\t\tKubectlVersion:    kubectlVersion}\n\n\tif err := templates.ExecuteTemplate(w, \"kubeconfig.html\", token_data); err != nil {\n\t\tlog.Println(err)\n\t\thttp.Error(w, http.StatusText(500), 500)\n\t}\n}\n\n// renderHTMLError renders an HTML page that presents an HTTP error.\nfunc (cluster *Cluster) renderHTMLError(w http.ResponseWriter, errorMsg string, code int) {\n\tw.Header().Set(\"Content-Type\", \"text/html; charset=utf-8\")\n\tw.Header().Set(\"X-Content-Type-Options\", \"nosniff\")\n\tw.WriteHeader(code)\n\n\tif err := templates.ExecuteTemplate(w, \"error.html\", map[string]string{\n\t\t\"Logo_Uri\":          cluster.Config.Logo_Uri,\n\t\t\"Web_Path_Prefix\":   cluster.Config.Web_Path_Prefix,\n\t\t\"Code\":              fmt.Sprintf(\"%d\", code),\n\t\t\"Error_Description\": errorMsg,\n\t}); err != nil {\n\t\tlog.Println(err)\n\t\thttp.Error(w, http.StatusText(500), 500)\n\t}\n}\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/dex-k8s-authenticator/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: dex-k8s-authenticator\n  namespace: network-system\nspec:\n  path: \"./apps/base/network-system/dex-k8s-authenticator/app\"\n  wait: true\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: dex-k8s-authenticator\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/echo-server/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app echo-server\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      echo-server:\n        replicas: 1\n        strategy: RollingUpdate\n        containers:\n          app:\n            image:\n              repository: ghcr.io/mendhak/http-https-echo\n              tag: 40\n            env:\n              HTTP_PORT: &port 80\n              LOG_WITHOUT_NEWLINE: true\n              LOG_IGNORE_PATH: /healthz\n              PROMETHEUS_ENABLED: true\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /healthz\n                    port: *port\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n              seccompProfile:\n                type: RuntimeDefault\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 128Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: *app\n        ports:\n          http:\n            port: *port\n    serviceMonitor:\n      app:\n        serviceName: *app\n        endpoints:\n          - port: http\n            scheme: http\n            path: /metrics\n            interval: 1m\n            scrapeTimeout: 10s\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/echo-server/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: echo-server\n  namespace: network-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'echo.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: echo-server\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/echo-server/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/echo-server/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: echo-server\n  namespace: network-system\nspec:\n  path: \"./apps/base/network-system/echo-server/app\"\n  wait: true\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: echo-server\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/certificates.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json\napiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: owncloud-ai-le\nspec:\n  # The secret name where cert-manager should store the signed certificate\n  secretName: owncloud-ai-le\n  duration: 2160h0m0s # 90d\n  renewBefore: 360h0m0s # 15d\n  # cert-manager regenerates a new private key on each issuance\n  # https://cert-manager.io/docs/usage/certificate/#rotation-private-key\n  privateKey:\n    rotationPolicy: Always\n    algorithm: ECDSA\n    encoding: PKCS8\n    size: 256\n  usages:\n    - server auth\n    - client auth\n  issuerRef:\n    name: letsencrypt-prod\n    kind: ClusterIssuer\n  commonName: ${CLUSTER_DOMAIN}\n  dnsNames:\n    - ${CLUSTER_DOMAIN}\n    - '*.${CLUSTER_DOMAIN}'\n    - '*.preview.${CLUSTER_DOMAIN}'\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/envoy.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.envoyproxy.io/envoyproxy_v1alpha1.json\napiVersion: gateway.envoyproxy.io/v1alpha1\nkind: EnvoyProxy\nmetadata:\n  name: envoy\nspec:\n  logging:\n    level:\n      default: info\n  provider:\n    type: Kubernetes\n    kubernetes:\n      envoyDeployment:\n        replicas: 3\n        container:\n          imageRepository: mirror.gcr.io/envoyproxy/envoy\n          resources:\n            requests:\n              cpu: 200m\n              memory: 512Mi\n            limits:\n              memory: 2Gi\n        pod:\n          topologySpreadConstraints:\n            - maxSkew: 1\n              topologyKey: kubernetes.io/hostname\n              whenUnsatisfiable: DoNotSchedule\n              labelSelector:\n                matchLabels:\n                  gateway.envoyproxy.io/owning-gateway-name: envoy-external\n      envoyService:\n        externalTrafficPolicy: Local\n  shutdown:\n    drainTimeout: 180s\n  telemetry:\n    accessLog:\n      settings:\n        - format:\n            type: Text\n            text: |\n              [%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\"\n          sinks:\n            - type: File\n              file:\n                path: /dev/stdout\n    metrics:\n      prometheus:\n        compression:\n          type: Zstd\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/gatewayclass.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/gatewayclass_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: GatewayClass\nmetadata:\n  name: envoy\nspec:\n  controllerName: gateway.envoyproxy.io/gatewayclass-controller\n  parametersRef:\n    group: gateway.envoyproxy.io\n    kind: EnvoyProxy\n    name: envoy\n    namespace: network-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/gateways.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/gateway_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: Gateway\nmetadata:\n  name: envoy-external\n  annotations:\n    external-dns.alpha.kubernetes.io/target: &hostname \"external.${CLUSTER_DOMAIN}\"\nspec:\n  gatewayClassName: envoy\n  infrastructure:\n    annotations:\n      external-dns.alpha.kubernetes.io/hostname: *hostname\n      lbipam.cilium.io/ips: ${CLUSTER_LB_ENVOY_EXT_GATEWAY_API}\n  addresses:\n    - type: IPAddress\n      value: ${CLUSTER_LB_ENVOY_EXT_GATEWAY_API}\n  listeners:\n    - name: http\n      protocol: HTTP\n      port: 80\n      allowedRoutes:\n        namespaces:\n          from: Same\n    - name: https\n      protocol: HTTPS\n      port: 443\n      allowedRoutes:\n        namespaces:\n          from: All\n      tls:\n        mode: Terminate\n        certificateRefs:\n          - kind: Secret\n            name: owncloud-ai-le\n    - name: minecraft-bedrock\n      protocol: UDP\n      port: 19131\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: minecraft-bedrock-broadcaster\n      protocol: UDP\n      port: 19133\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: minecraft-java\n      protocol: TCP\n      port: 25565\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: enemy-territory\n      protocol: UDP\n      port: 27960\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: cmangos-auth\n      protocol: TCP\n      port: 3724\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: cmangos-world\n      protocol: TCP\n      port: 8085\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: cmangos-world-ptr\n      protocol: TCP\n      port: 8086\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: azerothcore-auth\n      protocol: TCP\n      port: 3725\n      allowedRoutes:\n        namespaces:\n          from: All\n    - name: azerothcore-world\n      protocol: TCP\n      port: 3726\n      allowedRoutes:\n        namespaces:\n          from: All\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/gateway_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: Gateway\nmetadata:\n  name: envoy-internal\n  annotations:\n    external-dns.alpha.kubernetes.io/target: &hostname \"internal.${CLUSTER_DOMAIN}\"\nspec:\n  gatewayClassName: envoy\n  infrastructure:\n    annotations:\n      external-dns.alpha.kubernetes.io/hostname: *hostname\n      lbipam.cilium.io/ips: ${CLUSTER_LB_ENVOY_INT_GATEWAY_API}\n  addresses:\n    - type: IPAddress\n      value: ${CLUSTER_LB_ENVOY_INT_GATEWAY_API}\n  listeners:\n    - name: http\n      protocol: HTTP\n      port: 80\n      allowedRoutes:\n        namespaces:\n          from: Same\n    - name: https\n      protocol: HTTPS\n      port: 443\n      allowedRoutes:\n        namespaces:\n          from: All\n      tls:\n        mode: Terminate\n        certificateRefs:\n          - kind: Secret\n            name: owncloud-ai-le\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/grafanadashboards.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: envoy-gateway\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://raw.githubusercontent.com/envoyproxy/gateway/refs/heads/main/charts/gateway-addons-helm/dashboards/envoy-gateway-global.json\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: envoy-proxy\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://raw.githubusercontent.com/envoyproxy/gateway/refs/heads/main/charts/gateway-addons-helm/dashboards/envoy-proxy-global.json\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: envoy-overview\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/24459/revisions/1/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: envoy-upstream\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/24457/revisions/1/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: envoy-downstream\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/24458/revisions/1/download\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app envoy-gateway\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: envoy-gateway\n  values:\n    deployment:\n      priorityClassName: platform-cluster-critical\n    global:\n      imageRegistry: mirror.gcr.io\n    config:\n      envoyGateway:\n        provider:\n          type: Kubernetes\n          kubernetes:\n            deploy:\n              type: GatewayNamespace\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/httproutes.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: https-redirect\n  annotations:\n    external-dns.alpha.kubernetes.io/controller: none\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: http\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: http\n  rules:\n    - filters:\n        - type: RequestRedirect\n          requestRedirect:\n            scheme: https\n            statusCode: 301\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - certificates.yaml\n  - envoy.yaml\n  - gatewayclass.yaml\n  - gateways.yaml\n  - grafanadashboards.yaml\n  - helmrelease.yaml\n  - httproutes.yaml\n  - monitors.yaml\n  - ocirepository.yaml\n  - pdb.yaml\n  - policies.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/monitors.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/podmonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PodMonitor\nmetadata:\n  name: envoy-proxy\nspec:\n  jobLabel: envoy-proxy\n  namespaceSelector:\n    matchNames:\n      - network-system\n  podMetricsEndpoints:\n    - port: metrics\n      path: /stats/prometheus\n      honorLabels: true\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: proxy\n      app.kubernetes.io/name: envoy\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/servicemonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: envoy-gateway\nspec:\n  endpoints:\n    - port: metrics\n      path: /metrics\n      honorLabels: true\n  jobLabel: envoy-gateway\n  namespaceSelector:\n    matchNames:\n      - network-system\n  selector:\n    matchLabels:\n      control-plane: envoy-gateway\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: envoy-gateway\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.8.0\n  url: oci://mirror.gcr.io/envoyproxy/gateway-helm\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/pdb.yaml",
    "content": "---\napiVersion: policy/v1\nkind: PodDisruptionBudget\nmetadata:\n  name: envoy-gateway\nspec:\n  minAvailable: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/instance: envoy-gateway\n      app.kubernetes.io/name: gateway-helm\n      control-plane: envoy-gateway\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/app/policies.yaml",
    "content": "---\napiVersion: gateway.envoyproxy.io/v1alpha1\nkind: BackendTrafficPolicy\nmetadata:\n  name: envoy-default\nspec:\n  targetSelectors:\n    - group: gateway.networking.k8s.io\n      kind: Gateway\n  compressor:\n    - type: Zstd\n    - type: Brotli\n    - type: Gzip\n  retry:\n    numRetries: 2\n    retryOn:\n      triggers:\n        - reset\n  tcpKeepalive:\n    probes: 3\n    idleTime: 20m\n    interval: 60s\n  timeout:\n    http:\n      requestTimeout: \"0s\"\n---\napiVersion: gateway.envoyproxy.io/v1alpha1\nkind: ClientTrafficPolicy\nmetadata:\n  name: envoy-default\nspec:\n  targetSelectors:\n    - group: gateway.networking.k8s.io\n      kind: Gateway\n  timeout:\n    http:\n      # Increase stream idle timeout from default 5m to prevent SSE/WebSocket disconnections\n      streamIdleTimeout: \"1h\"\n  clientIPDetection:\n    xForwardedFor:\n      numTrustedHops: 1\n  http2:\n    onInvalidMessage: TerminateStream\n  http3: {}\n  tcpKeepalive:\n    probes: 3\n    idleTime: 20m\n    interval: 60s\n  tls:\n    minVersion: \"1.2\"\n    alpnProtocols:\n      - h2\n      - http/1.1\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/envoy-gateway/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: envoy-gateway\n  namespace: network-system\nspec:\n  path: \"./apps/base/network-system/envoy-gateway/app\"\n  wait: true\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: envoy-gateway\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: external-dns-cloudflare\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: external-dns-cloudflare\n    template:\n      data:\n        CLOUDFLARE_API_TOKEN: \"{{ .CLOUDFLARE_API_TOKEN }}\"\n  dataFrom:\n    - extract:\n        key: cloudflare\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: cloudflare-tunnels\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15038/revisions/3/download\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app external-dns\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: external-dns\n  valuesFrom:\n    - kind: ConfigMap\n      name: external-dns-values\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n  - pdb.yaml\n  - prometheusrule.yaml\n\nconfigMapGenerator:\n  - name: external-dns-values\n    namespace: network-system\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: external-dns\n  namespace: network-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.21.1\n  url: oci://ghcr.io/home-operations/charts-mirror/external-dns\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/pdb.yaml",
    "content": "---\napiVersion: policy/v1\nkind: PodDisruptionBudget\nmetadata:\n  name: external-dns\nspec:\n  minAvailable: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/instance: external-dns\n      app.kubernetes.io/name: external-dns\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/prometheusrule.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/prometheusrule_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  name: external-dns-rules\nspec:\n  groups:\n    - name: external-dns.rules\n      rules:\n        - alert: ExternalDNSStale\n          expr: |-\n            time() - external_dns_controller_last_sync_timestamp_seconds > 900\n          for: 1h\n          annotations:\n            summary: >-\n              ExternalDNS ({{ $labels.job }}) has not synced successfully in over 15 minutes\n          labels:\n            severity: warning\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/app/values.yaml",
    "content": "priorityClassName: platform-cluster-critical\nprovider:\n  name: cloudflare\ndomainFilters:\n  - \"${CLUSTER_DOMAIN}\"\nenv:\n  - name: CF_API_TOKEN\n    valueFrom:\n      secretKeyRef:\n        key: CLOUDFLARE_API_TOKEN\n        name: external-dns-cloudflare\nextraArgs:\n  - --cloudflare-proxied\n  - --crd-source-apiversion=externaldns.k8s.io/v1alpha1\n  - --crd-source-kind=DNSEndpoint\n  - --annotation-filter=external-dns.alpha.kubernetes.io/external=true\n  - --gateway-name=envoy-external\npolicy: sync\ntriggerLoopOnEvent: true\ntxtPrefix: k8s.\nsources:\n  - crd\n  - gateway-httproute\nserviceMonitor:\n  enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: external-dns\n  namespace: network-system\nspec:\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n  path: \"./apps/base/network-system/external-dns/app\"\n  wait: true\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: external-dns\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns-unifi/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: external-dns-unifi\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: external-dns-unifi\n    template:\n      data:\n        UNIFI_API_KEY: \"{{ .UNIFI_API_KEY }}\"\n  dataFrom:\n    - extract:\n        key: unifi\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns-unifi/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app external-dns-unifi\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: external-dns-unifi\n  valuesFrom:\n    - kind: ConfigMap\n      name: external-dns-unifi-values\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns-unifi/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: external-dns-unifi-values\n    namespace: network-system\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns-unifi/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns-unifi/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: external-dns-unifi\n  namespace: network-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 1.21.1\n  url: oci://ghcr.io/home-operations/charts-mirror/external-dns\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns-unifi/app/values.yaml",
    "content": "fullnameOverride: external-dns-unifi\nprovider:\n  name: webhook\n  webhook:\n    image:\n      repository: ghcr.io/kashalls/external-dns-unifi-webhook\n      tag: v0.8.2@sha256:7f0ddbbc83a36a2a9d762e25eef9cafcb3adf0493068a27d72ae71087eafe6f0\n    env:\n      - name: UNIFI_HOST\n        value: https://192.168.1.1\n      - name: UNIFI_API_KEY\n        valueFrom:\n          secretKeyRef:\n            name: &secret external-dns-unifi\n            key: UNIFI_API_KEY\n    livenessProbe:\n      httpGet:\n        path: /healthz\n        port: http-webhook\n      initialDelaySeconds: 10\n      timeoutSeconds: 5\n    readinessProbe:\n      httpGet:\n        path: /readyz\n        port: http-webhook\n      initialDelaySeconds: 10\n      timeoutSeconds: 5\ntriggerLoopOnEvent: true\npolicy: sync\nsources:\n  - gateway-httproute\nextraArgs:\n  - --gateway-name=envoy-internal\ntxtOwnerId: unifi\ntxtPrefix: k8s.unifi.\ndomainFilters:\n  - ${CLUSTER_DOMAIN}\nserviceMonitor:\n  enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/external-dns-unifi/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: external-dns-unifi\n  namespace: network-system\nspec:\n  dependsOn:\n    - name: external-dns\n      namespace: network-system\n    - name: onepassword\n      namespace: external-secrets\n  path: \"./apps/base/network-system/external-dns-unifi/app\"\n  wait: true\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: external-dns-unifi\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: network-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/multus/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app multus\n  namespace: network-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  values:\n    controllers:\n      *app :\n        type: daemonset\n        pod:\n          hostNetwork: true\n        initContainers:\n          cni-plugins:\n            image:\n              repository: ghcr.io/home-operations/cni-plugins\n              tag: 1.9.1@sha256:56222d9cf686632f0951103a400adeeec8d982aaf8cbf4d21588da17a41dd228\n        containers:\n          app:\n            image:\n              repository: ghcr.io/k8snetworkplumbingwg/multus-cni\n              tag: latest@sha256:f4e21d437fe5407e23264ae4b66f0e52db9a07f77a37fc1d61cd3923405871a9\n            command:\n              - /thin_entrypoint\n            args:\n              - --cleanup-config-on-exit\n            securityContext:\n              privileged: true\n            resources:\n              requests:\n                cpu: 10m\n                memory: 32Mi\n              limits:\n                memory: 256Mi\n        serviceAccount:\n          identifier: multus\n    persistence:\n      etc-cni-net-d:\n        type: hostPath\n        hostPath: /etc/cni/net.d\n        globalMounts:\n          - path: /host/etc/cni/net.d\n      opt-cni-bin:\n        type: hostPath\n        hostPath: /opt/cni/bin\n        globalMounts:\n          - path: /host/opt/cni/bin\n    serviceAccount:\n      multus: {}\n    defaultPodOptions:\n      tolerations:\n        - key: \"node-role.kubernetes.io/control-plane\"\n          operator: \"Exists\"\n          effect: \"NoSchedule\"\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/multus/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - rbac.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/multus/app/rbac.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: multus\nrules:\n  - apiGroups: [\"k8s.cni.cncf.io\"]\n    resources: [\"*\"]\n    verbs: [\"*\"]\n  - apiGroups: [\"\"]\n    resources: [\"pods\", \"pods/status\"]\n    verbs: [\"get\", \"update\"]\n  - apiGroups: [\"\", \"events.k8s.io\"]\n    resources: [\"events\"]\n    verbs: [\"create\", \"patch\", \"update\"]\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: multus\nroleRef:\n  kind: ClusterRole\n  name: multus\n  apiGroup: rbac.authorization.k8s.io\nsubjects:\n  - kind: ServiceAccount\n    name: multus\n    namespace: network-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/multus/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: multus\n  namespace: network-system\nspec:\n  path: \"./apps/base/network-system/multus/app\"\n  wait: true\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: multus\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: multus-networks\n  namespace: network-system\nspec:\n  path: \"./apps/base/network-system/multus/networks\"\n  wait: true\n  dependsOn:\n    - name: multus\n      namespace: network-system\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: multus-networks\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/multus/networks/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - network.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/multus/networks/network.yaml",
    "content": "---\napiVersion: k8s.cni.cncf.io/v1\nkind: NetworkAttachmentDefinition\nmetadata:\n  name: wifi-network\n  namespace: network-system\nspec:\n  config: |-\n    {\n      \"cniVersion\": \"0.3.1\",\n      \"name\": \"wifi-network\",\n      \"plugins\": [\n        {\n          \"type\": \"macvlan\",\n          \"master\": \"enp2s0\",\n          \"mode\": \"bridge\",\n          \"ipam\": {\n            \"type\": \"host-local\",\n            \"subnet\": \"192.168.86.0/24\",\n            \"rangeStart\": \"192.168.86.100\",\n            \"rangeEnd\": \"192.168.86.200\",\n            \"routes\": [\n              { \"dst\": \"0.0.0.0/0\", \"gw\": \"192.168.86.1\" }\n            ]\n          }\n        }\n      ]\n    }\n---\napiVersion: k8s.cni.cncf.io/v1\nkind: NetworkAttachmentDefinition\nmetadata:\n  name: lan-network\n  namespace: network-system\nspec:\n  config: |-\n    {\n      \"cniVersion\": \"0.3.1\",\n      \"name\": \"lan-network\",\n      \"plugins\": [\n        {\n          \"type\": \"macvlan\",\n          \"master\": \"enp2s0\",\n          \"mode\": \"bridge\",\n          \"ipam\": {\n            \"type\": \"host-local\",\n            \"subnet\": \"192.168.50.0/24\",\n            \"rangeStart\": \"192.168.50.100\",\n            \"rangeEnd\": \"192.168.50.200\",\n            \"routes\": [\n              { \"dst\": \"0.0.0.0/0\", \"gw\": \"192.168.50.1\" }\n            ]\n          }\n        }\n      ]\n    }\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: network-system\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/oauth2-proxy/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: oauth2-proxy-dex\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: oauth2-proxy-dex\n    template:\n      data:\n        client-id: \"{{ .CLIENT_ID }}\"\n        client-secret: \"{{ .CLIENT_SECRET }}\"\n        cookie-secret: \"{{ .COOKIE_SECRET }}\"\n  dataFrom:\n    - extract:\n        key: dex\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/oauth2-proxy/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app oauth2-proxy\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: oauth2-proxy\n  dependsOn:\n    - name: dex\n      namespace: network-system\n    - name: cert-manager\n      namespace: network-system\n  values:\n    metrics:\n      servicemonitor:\n        enabled: true\n    config:\n      existingSecret: oauth2-proxy-dex\n      configFile: |\n        provider = \"oidc\"\n        oidc_issuer_url = \"https://dex.${CLUSTER_DOMAIN}\"\n        auth_logging = true\n        cookie_domains = \".${CLUSTER_DOMAIN}\"\n        cookie_httponly = true\n        cookie_name = \"_owncloud_oauth\"\n        cookie_refresh = \"1h\"\n        cookie_samesite = \"lax\"\n        cookie_secure = true\n        email_domains = [ \"*\" ]\n        pass_access_token = true\n        pass_authorization_header = true\n        pass_basic_auth = false\n        request_logging = true\n        session_store_type = \"cookie\"\n        silence_ping_logging = true\n        set_authorization_header = true\n        set_xauthrequest = true\n        skip_jwt_bearer_tokens = true\n        skip_provider_button = true\n        ssl_insecure_skip_verify = false\n        standard_logging = true\n        upstreams = [ \"static://200\" ]\n        whitelist_domains = \".${CLUSTER_DOMAIN}\"\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/oauth2-proxy/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: auth\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'auth.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: oauth2-proxy\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/oauth2-proxy/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n  - httproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/oauth2-proxy/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: oauth2-proxy\n  namespace: network-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 10.4.3\n  url: oci://ghcr.io/oauth2-proxy/charts/oauth2-proxy\n"
  },
  {
    "path": "kubernetes/apps/base/network-system/oauth2-proxy/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: oauth2-proxy\n  namespace: network-system\nspec:\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n  path: \"./apps/base/network-system/oauth2-proxy/app\"\n  wait: true\n  targetNamespace: network-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: oauth2-proxy\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/nginx-ingress/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: nginx-ingress\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/nginx-ingress/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: nginx-ingress\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: privileged\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/nginx-ingress/nginx-ingress/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app nginx-ingress\n  namespace: nginx-ingress\nspec:\n  interval: 1h\n  releaseName: ingress-nginx\n  chart:\n    spec:\n      chart: ingress-nginx\n      version: 4.15.1\n      sourceRef:\n        kind: HelmRepository\n        name: ingress-nginx-chart\n        namespace: flux-system\n      interval: 10m\n  values:\n    tcp:\n      '25565': \"game-servers/minecraft:25565\"\n    udp:\n      '19131': \"game-servers/minecraft-bedrock-minecraft-bedrock:19131\"\n      '19132': \"game-servers/minecraft:19132\"\n    controller:\n      service:\n        enableHttp: true\n        enableHttps: true\n        annotations:\n          lbipam.cilium.io/ips: ${CLUSTER_LB_NGINX_INGRESS_GATEWAY}\n      metrics:\n        enabled: true\n        serviceMonitor:\n          enabled: true\n          namespace: nginx-ingress\n          namespaceSelector:\n            any: true\n      config:\n        # https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#proxy-stream-responses\n        proxy-stream-responses: '999999'\n        enable-real-ip: \"true\"\n        use-forwarded-headers: \"true\"\n        enable-ocsp: \"true\"\n        force-ssl-redirect: \"true\"\n        log-format-escape-json: \"true\"\n        ssl-protocols: TLSv1.3\n        hsts-max-age: 31449600\n        keep-alive: 120\n        keep-alive-requests: 10000\n        proxy-connect-timeout: 120\n        proxy-read-timeout: 120\n        proxy-send-timeout: 120\n      extraArgs:\n        default-ssl-certificate: 'network-system/owncloud-ai-le'\n      replicaCount: 2\n      resources:\n        limits:\n          memory: 512Mi\n        requests:\n          cpu: 25m\n          memory: 256Mi\n      podDisruptionBudget:\n        enabled: true\n        minAvailable: 1\n"
  },
  {
    "path": "kubernetes/apps/base/nginx-ingress/nginx-ingress/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/nginx-ingress/nginx-ingress/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: nginx-ingress\n  namespace: nginx-ingress\nspec:\n  path: \"./apps/base/nginx-ingress/nginx-ingress/app\"\n  wait: true\n  targetNamespace: nginx-ingress\n  sourceRef:\n    kind: ExternalArtifact\n    name: nginx-ingress\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/blackbox-exporter/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: blackbox-exporter\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: blackbox-exporter\n  valuesFrom:\n    - kind: ConfigMap\n      name: blackbox-exporter-values\n"
  },
  {
    "path": "kubernetes/apps/base/observability/blackbox-exporter/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n  - probes.yaml\n\nconfigMapGenerator:\n  - name: blackbox-exporter-values\n    namespace: observability\n    files:\n      - values.yaml=./values.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/blackbox-exporter/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/observability/blackbox-exporter/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: blackbox-exporter\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 11.10.0\n  url: oci://ghcr.io/prometheus-community/charts/prometheus-blackbox-exporter\n"
  },
  {
    "path": "kubernetes/apps/base/observability/blackbox-exporter/app/probes.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/probe_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: Probe\nmetadata:\n  name: icmp\nspec:\n  module: icmp\n  prober:\n    url: blackbox-exporter.observability.svc.cluster.local:9115\n  targets:\n    staticConfig:\n      static:\n        - expanse.internal\n        # - jetkvm-01.internal\n        # - jetkvm-02.internal\n        # - jetkvm-03.internal\n  metricRelabelings:\n    - targetLabel: service\n      replacement: blackbox-exporter\n      action: replace\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/probe_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: Probe\nmetadata:\n  name: tcp\nspec:\n  module: tcp_connect\n  prober:\n    url: blackbox-exporter.observability.svc.cluster.local:9115\n  targets:\n    staticConfig:\n      static:\n        - expanse.internal:2049\n  metricRelabelings:\n    - targetLabel: service\n      replacement: blackbox-exporter\n      action: replace\n"
  },
  {
    "path": "kubernetes/apps/base/observability/blackbox-exporter/app/values.yaml",
    "content": "fullnameOverride: blackbox-exporter\nsecurityContext:\n  readOnlyRootFilesystem: true\n  allowPrivilegeEscalation: false\n  capabilities: { add: [\"NET_RAW\"] }\nconfig:\n  modules:\n    http_2xx:\n      prober: http\n      timeout: 5s\n      http:\n        valid_http_versions:\n          - HTTP/1.1\n          - HTTP/2.0\n        follow_redirects: true\n        preferred_ip_protocol: ip4\n    icmp:\n      prober: icmp\n      timeout: 5s\n      icmp:\n        preferred_ip_protocol: ip4\n    tcp_connect:\n      prober: tcp\n      timeout: 5s\n      tcp:\n        preferred_ip_protocol: ip4\nserviceMonitor:\n  enabled: true\n  selfMonitor:\n    enabled: true\nprometheusRule:\n  enabled: true\n  rules:\n    - alert: LanProbeFailed\n      expr: |-\n        probe_success{ service=\"blackbox-exporter\" } == 0\n      for: 1h\n      labels:\n        severity: warning\n      annotations:\n        summary: |-\n          The probe targeting {{ $labels.instance }} is currently having connectivity issues\n"
  },
  {
    "path": "kubernetes/apps/base/observability/blackbox-exporter/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: blackbox-exporter\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/blackbox-exporter/app\"\n  wait: true\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: blackbox-exporter\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: grafana\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: grafana-operator\n  values:\n    dashboard:\n      enabled: true\n    serviceMonitor:\n      enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: grafana-operator\n  namespace: observability\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 5.22.2\n  url: oci://ghcr.io/grafana/helm-charts/grafana-operator\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/instance/grafana.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafana_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: Grafana\nmetadata:\n  name: grafana\n  labels:\n    grafana.internal/instance: grafana\nspec:\n  config:\n    analytics:\n      check_for_updates: \"false\"\n      check_for_plugin_updates: \"false\"\n      feedback_links_enabled: \"false\"\n      reporting_enabled: \"false\"\n    auth:\n      disable_login_form: \"true\"\n    auth.generic_oauth:\n      auto_login: \"true\"\n      # For variables see https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#env-provider\n      enabled: \"true\"\n      name: \"GitHub SSO\"\n      allow_sign_up: \"true\"\n      client_id: ${GRAFANA_AUTH_GENERIC_CLIENT_ID}\n      client_secret: ${GRAFANA_AUTH_GENERIC_CLIENT_SECRET}\n      scopes: \"openid profile email groups\"\n      email_attribute_path: email\n      login_attribute_path: username\n      name_attribute_path: full_name\n      groups_attribute_path: groups\n      auth_url: \"https://dex.${CLUSTER_DOMAIN}/auth\"\n      token_url: \"https://dex.${CLUSTER_DOMAIN}/token\"\n      api_url: \"https://dex.${CLUSTER_DOMAIN}/userinfo\"\n      role_attribute_path: \"contains(groups[*], 'raspbernetes:k8s-admins') && 'Admin' || contains(groups[*], 'people') && 'Viewer'\"\n    log:\n      mode: console\n    metrics:\n      enabled: \"true\"\n    news:\n      news_feed_enabled: \"false\"\n    plugins:\n      plugin_admin_enabled: \"false\"\n    security:\n      angular_support_enabled: \"true\"\n    server:\n      enable_gzip: \"true\"\n      root_url: https://grafana.${CLUSTER_DOMAIN}\n    smtp:\n      enabled: \"true\"\n      host: \"smtp-relay.home-system.svc.cluster.local:25\"\n      from_address: \"noreply@owncloud.ai\"\n      from_name: \"Grafana\"\n      skip_verify: \"true\"\n  deployment:\n    spec:\n      strategy:\n        type: Recreate\n      template:\n        spec:\n          containers:\n            - name: grafana\n              env:\n                - name: GF_SECURITY_ADMIN_PASSWORD\n                  valueFrom:\n                    secretKeyRef:\n                      name: grafana-admin-credentials\n                      key: GF_SECURITY_ADMIN_PASSWORD\n              securityContext:\n                allowPrivilegeEscalation: false\n                readOnlyRootFilesystem: true\n                capabilities: { drop: [\"ALL\"] }\n          securityContext:\n            runAsNonRoot: true\n            runAsUser: 1000\n            runAsGroup: 1000\n            fsGroup: 1000\n            fsGroupChangePolicy: OnRootMismatch\n          volumes:\n            - name: grafana-data\n              persistentVolumeClaim:\n                claimName: grafana-pvc\n  persistentVolumeClaim:\n    spec:\n      accessModes:\n        - ReadWriteOnce\n      resources:\n        requests:\n          storage: 10Gi\n      storageClassName: ceph-block\n  disableDefaultSecurityContext: All\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/instance/grafanadatasource.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadatasource_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDatasource\nmetadata:\n  name: prometheus\nspec:\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasource:\n    type: prometheus\n    name: prometheus\n    access: proxy\n    isDefault: true\n    url: http://prometheus-operated.observability.svc.cluster.local:9090\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadatasource_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDatasource\nmetadata:\n  name: alertmanager\nspec:\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasource:\n    type: alertmanager\n    name: alertmanager\n    access: proxy\n    jsonData:\n      implementation: prometheus\n    url: http://alertmanager-operated.observability.svc.cluster.local:9093\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/instance/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: grafana\n  namespace: observability\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'grafana.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: grafana-service\n          port: 3000\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/instance/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - grafana.yaml\n  - grafanadatasource.yaml\n  - httproute.yaml\n  - replicationsource.yaml\n  - servicemonitor.yaml\n  - volsync-externalsecret.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/instance/replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: grafana\nspec:\n  sourcePVC: grafana-pvc\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 1000\n      fsGroup: 1000\n    parallelism: 2\n    repository: grafana-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/instance/servicemonitor.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/servicemonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: grafana\nspec:\n  endpoints:\n    - port: grafana\n      path: /metrics\n      honorLabels: true\n  jobLabel: grafana\n  namespaceSelector:\n    matchNames:\n      - observability\n  selector:\n    matchLabels:\n      grafana.internal/instance: grafana\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/instance/volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: grafana-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: grafana-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/observability/grafana/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: grafana\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/grafana/app\"\n  wait: true\n  dependsOn:\n    - name: cert-manager\n      namespace: network-system\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: grafana\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: grafana-instance\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/grafana/instance\"\n  wait: true\n  dependsOn:\n    - name: grafana\n      namespace: observability\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: grafana-instance\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kromgo/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kromgo\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  dependsOn:\n    - name: kube-prometheus-stack\n      namespace: observability\n  values:\n    controllers:\n      kromgo:\n        replicas: 1\n        strategy: RollingUpdate\n        containers:\n          app:\n            image:\n              repository: ghcr.io/kashalls/kromgo\n              tag: v0.10.0@sha256:965ecc92d68dc1a4a969397855367bbc70da03227a941ea607b73bb7e0b78fd6\n            env:\n              PROMETHEUS_URL: http://kube-prometheus-stack-prometheus.observability.svc.cluster.local:9090/\n              SERVER_PORT: &serverPort 80\n              HEALTH_PORT: &healthPort 8080\n            probes:\n              liveness: &probes\n                enabled: true\n                custom: true\n                spec:\n                  httpGet:\n                    path: /readyz\n                    port: *healthPort\n                  initialDelaySeconds: 0\n                  periodSeconds: 10\n                  timeoutSeconds: 1\n                  failureThreshold: 3\n              readiness: *probes\n            securityContext:\n              allowPrivilegeEscalation: false\n              readOnlyRootFilesystem: true\n              capabilities: { drop: [\"ALL\"] }\n            resources:\n              requests:\n                cpu: 10m\n              limits:\n                memory: 64Mi\n    defaultPodOptions:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        runAsGroup: 1000\n        seccompProfile: { type: RuntimeDefault }\n    service:\n      app:\n        controller: kromgo\n        ports:\n          http:\n            primary: true\n            port: *serverPort\n          health:\n            port: *healthPort\n    persistence:\n      config-file:\n        type: configMap\n        name: kromgo-config\n        globalMounts:\n          - path: /kromgo/config.yaml\n            subPath: config.yaml\n            readOnly: true\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kromgo/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: kromgo\n  namespace: observability\n  annotations:\n    external-dns.alpha.kubernetes.io/external: 'true'\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'kromgo.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: kromgo\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kromgo/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n\nconfigMapGenerator:\n  - name: kromgo-config\n    files:\n      - config.yaml=./resources/config.yaml\n\ngeneratorOptions:\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kromgo/app/kustomizeconfig.yaml",
    "content": "nameReference:\n- kind: ConfigMap\n  version: v1\n  fieldSpecs:\n  - path: spec/values/persistence/config-file/name\n    kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kromgo/app/resources/config.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/kashalls/kromgo/main/config.schema.json\nbadge:\n  font: Verdana.ttf\n  size: 12\n\nmetrics:\n  - name: talos_version\n    query: label_replace(node_os_info{name=\"Talos\"}, \"version_id\", \"$1\", \"version_id\", \"v(.+)\")\n    label: version_id\n    title: Talos\n\n  - name: kubernetes_version\n    query: label_replace(kubernetes_build_info{service=\"kubernetes\"}, \"git_version\", \"$1\", \"git_version\", \"v(.+)\")\n    label: git_version\n    title: Kubernetes\n\n  - name: flux_version\n    query: label_replace(flux_instance_info, \"revision\", \"$1\", \"revision\", \"v(.+)@sha256:.+\")\n    label: revision\n    title: Flux\n\n  - name: cluster_node_count\n    query: count(count by (node) (kube_node_status_condition{condition=\"Ready\"}))\n    colors:\n      - { color: \"green\", min: 0, max: 9999 }\n    title: Nodes\n\n  - name: cluster_pod_count\n    query: sum(kube_pod_status_phase{phase=\"Running\"})\n    colors:\n      - { color: \"green\", min: 0, max: 9999 }\n    title: Pods\n\n  - name: cluster_cpu_usage\n    query: round(avg(instance:node_cpu_utilisation:rate5m{pod!=\"\"}) * 100, 0.1)\n    suffix: \"%\"\n    colors:\n      - { color: \"green\", min: 0, max: 35 }\n      - { color: \"orange\", min: 36, max: 75 }\n      - { color: \"red\", min: 76, max: 9999 }\n    title: CPU\n\n  - name: cluster_memory_usage\n    query: round(sum(node_memory_MemTotal_bytes{pod!=\"\"} - node_memory_MemAvailable_bytes{pod!=\"\"}) / sum(node_memory_MemTotal_bytes{pod!=\"\"}) * 100, 0.1)\n    suffix: \"%\"\n    colors:\n      - { color: \"green\", min: 0, max: 35 }\n      - { color: \"orange\", min: 36, max: 75 }\n      - { color: \"red\", min: 76, max: 9999 }\n    title: Memory\n\n  - name: cluster_power_usage\n    query: round(upsHighPrecOutputLoad, 0.1)\n    suffix: \"w\"\n    colors:\n      - { color: \"green\", min: 0, max: 400 }\n      - { color: \"orange\", min: 401, max: 750 }\n      - { color: \"red\", min: 751, max: 9999 }\n    title: Power\n\n  - name: cluster_age_days\n    query: round((time() - min(kube_node_created) ) / 86400)\n    suffix: \"d\"\n    colors:\n      - { color: \"green\", min: 0, max: 180 }\n      - { color: \"orange\", min: 181, max: 360 }\n      - { color: \"red\", min: 361, max: 9999 }\n    title: Age\n\n  - name: cluster_uptime_days\n    query: round(avg(node_time_seconds{pod!=\"\"} - node_boot_time_seconds{pod!=\"\"}) / 86400)\n    suffix: \"d\"\n    colors:\n      - { color: \"green\", min: 0, max: 180 }\n      - { color: \"orange\", min: 181, max: 360 }\n      - { color: \"red\", min: 361, max: 9999 }\n    title: Uptime\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kromgo/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kromgo\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/kromgo/app\"\n  wait: true\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: kromgo\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/README.md",
    "content": "# kube-prometheus-stack\n\n## NAS Deployments\n\n### node-exporter\n\n```yaml\nservices:\n  node-exporter:\n    command:\n      - '--path.rootfs=/host/root'\n      - '--path.procfs=/host/proc'\n      - '--path.sysfs=/host/sys'\n      - '--path.udev.data=/host/root/run/udev/data'\n      - '--web.listen-address=0.0.0.0:9100'\n      - >-\n        --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)\n    image: quay.io/prometheus/node-exporter:v1.9.0\n    network_mode: host\n    ports:\n      - '9100:9100'\n    restart: always\n    volumes:\n      - /:/host/root:ro\n      - /proc:/host/proc:ro\n      - /sys:/host/sys:ro\n```\n\n### smartctl-exporter\n\n```yaml\nservices:\n  smartctl-exporter:\n    command:\n      - '--smartctl.device-exclude=nvme0'\n    image: quay.io/prometheuscommunity/smartctl-exporter:v0.13.0\n    ports:\n      - '9633:9633'\n    privileged: True\n    restart: always\n    user: root\n```\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/alertmanager-replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: alertmanager\nspec:\n  sourcePVC: alertmanager-kube-prometheus-stack-db-alertmanager-kube-prometheus-stack-0\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 2000\n      fsGroup: 2000\n    parallelism: 2\n    repository: alertmanager-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/alertmanager-volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: alertmanager-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: alertmanager-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/alertmanagerconfig.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/alertmanagerconfig_v1alpha1.json\napiVersion: monitoring.coreos.com/v1alpha1\nkind: AlertmanagerConfig\nmetadata:\n  name: alertmanager\nspec:\n  route:\n    receiver: email\n    groupBy:\n      - namespace\n      - alertname\n      - job\n    groupWait: 24h\n    groupInterval: 1h\n    repeatInterval: 24h\n    routes:\n      # Drop Watchdog and InfoInhibitor — these are internal signals\n      - receiver: \"null\"\n        matchers:\n          - name: alertname\n            matchType: \"=~\"\n            value: \"InfoInhibitor|Watchdog\"\n        continue: false\n      # Drop maintenance-signal alerts — their only purpose is to be the\n      # source side of inhibit rules. Never email these.\n      - receiver: \"null\"\n        matchers:\n          - name: alertname\n            matchType: \"=~\"\n            value: \"NodeUnderMaintenance|FluxReconciliationInProgress\"\n        continue: false\n      # Drop etcd alerts that are noisy on Talos single-node etcd restarts\n      - receiver: \"null\"\n        matchers:\n          - name: alertname\n            matchType: \"=~\"\n            value: \"etcdHighNumberOfLeaderChanges|etcdMembersDown|etcdInsufficientMembers|etcdHighNumberOfFailedGRPCRequests|etcdHighCommitDurations\"\n          - name: severity\n            matchType: \"!=\"\n            value: critical\n        continue: false\n      # Drop Ceph PG alerts that are already muted/acknowledged in Ceph itself\n      - receiver: \"null\"\n        matchers:\n          - name: alertname\n            matchType: \"=~\"\n            value: \"CephPGsDamaged|CephOSDScrubErrors\"\n        continue: false\n      # Game-servers (WoW) — fast path. First email within 30s of any new\n      # alert in the namespace; subsequent alerts in the same group batched\n      # 5min apart; reminders only every 12h while still firing (and one\n      # final RESOLVED email when it clears, via sendResolved).\n      # Grouping by namespace + severity bundles related alerts into one\n      # email — e.g. all `critical game-servers` alerts arrive together\n      # rather than one email per alertname.\n      - receiver: email\n        matchers:\n          - name: namespace\n            matchType: \"=\"\n            value: game-servers\n          - name: severity\n            matchType: \"=~\"\n            value: critical|warning\n        groupBy:\n          - namespace\n          - severity\n        groupWait: 30s\n        groupInterval: 5m\n        repeatInterval: 12h\n        continue: false\n      # Critical alerts — only notify if sustained beyond 24h\n      - receiver: email\n        matchers:\n          - name: severity\n            matchType: \"=\"\n            value: critical\n        groupWait: 24h\n        repeatInterval: 24h\n        continue: false\n      # Warning alerts — only notify if sustained beyond 24h\n      - receiver: email\n        matchers:\n          - name: severity\n            matchType: \"=\"\n            value: warning\n        groupWait: 24h\n        repeatInterval: 24h\n        continue: false\n  receivers:\n    - name: \"null\"\n    - name: email\n      emailConfigs:\n        - to: \"${PRIVATE_EMAIL}\"\n          from: \"noreply@${CLUSTER_DOMAIN}\"\n          smarthost: \"smtp-relay.home-system.svc.cluster.local:25\"\n          requireTLS: false\n          sendResolved: true\n          headers:\n            - key: From\n              value: \"Alert Manager <noreply@${CLUSTER_DOMAIN}>\"\n            - key: Subject\n              value: '[{{ .Status | toUpper }}{{ if eq .Status \"firing\" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join \" \" }}'\n  inhibitRules:\n    # Critical silences warning/info for the same alert\n    - sourceMatch:\n        - name: severity\n          matchType: \"=\"\n          value: critical\n      targetMatch:\n        - name: severity\n          matchType: \"=~\"\n          value: warning|info\n      equal:\n        - namespace\n        - alertname\n    # InfoInhibitor silences info\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: InfoInhibitor\n      targetMatch:\n        - name: severity\n          matchType: \"=\"\n          value: info\n      equal:\n        - namespace\n    # KubePodCrashLooping inhibits KubePodNotReady for the same pod\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: KubePodCrashLooping\n      targetMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: KubePodNotReady\n      equal:\n        - namespace\n        - pod\n    # GameServerSegfault is the root cause — silence the downstream\n    # restart-pattern alerts for the same pod so we only get one email\n    # for one underlying problem.\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: GameServerSegfault\n      targetMatch:\n        - name: alertname\n          matchType: \"=~\"\n          value: \"GameServerCrashLooping|GameServerRecentRestarts|KubePodCrashLooping\"\n      equal:\n        - namespace\n        - pod\n    # GameServerCrashLooping inhibits the slower GameServerRecentRestarts\n    # for the same pod (same signal, different windows)\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: GameServerCrashLooping\n      targetMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: GameServerRecentRestarts\n      equal:\n        - namespace\n        - pod\n    # GameServerDown inhibits GameServerDegraded for the same deployment\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: GameServerDown\n      targetMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: GameServerDegraded\n      equal:\n        - namespace\n        - deployment\n    # Node-level alerts inhibit pod-level alerts on the same node\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=~\"\n          value: \"KubeNodeNotReady|KubeNodeUnreachable\"\n      targetMatch:\n        - name: severity\n          matchType: \"=~\"\n          value: warning|info\n      equal:\n        - node\n    # Planned maintenance: a cordoned/draining node suppresses\n    # warning/info alerts about pods and targets on that node.\n    # Critical alerts still fire — outages during a drain are real.\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: NodeUnderMaintenance\n      targetMatch:\n        - name: severity\n          matchType: \"=~\"\n          value: warning|info\n      equal:\n        - node\n    # In-flight Flux HelmRelease/Kustomization reconciles suppress\n    # warning/info alerts in the same workload namespace\n    # (KubePodNotReady, KubeDeploymentReplicasMismatch, TargetDown,\n    # etc.). Critical alerts still fire.\n    - sourceMatch:\n        - name: alertname\n          matchType: \"=\"\n          value: FluxReconciliationInProgress\n      targetMatch:\n        - name: severity\n          matchType: \"=~\"\n          value: warning|info\n      equal:\n        - namespace\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: kubernetes-api-server\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15761/revisions/21/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: kubernetes-coredns\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15762/revisions/22/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: kubernetes-global\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15757/revisions/43/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: kubernetes-namespaces\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15758/revisions/46/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: kubernetes-nodes\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15759/revisions/40/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: kubernetes-pods\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15760/revisions/39/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: kubernetes-volumes\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/11454/revisions/14/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: node-exporter-full\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/1860/revisions/45/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: prometheus\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/19105/revisions/9/download\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kube-prometheus-stack\n  namespace: observability\n  labels:\n    gitops.owncloud.ai/defaults: disabled\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kube-prometheus-stack\n  valuesFrom:\n    - kind: ConfigMap\n      name: flux-metrics-configmap\n      valuesKey: flux-metrics.yaml\n  install:\n    timeout: 1h\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n    force: true\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  dependsOn:\n    - name: grafana\n      namespace: observability\n  timeout: 30m\n  values:\n    cleanPrometheusOperatorObjectNames: true\n    # Disable alerts that produce false positives in Talos/homelab environments\n    defaultRules:\n      disabled:\n        # False positives from short-lived SA tokens on K8s 1.24+\n        KubeClientCertificateExpiration: true\n        # Extremely noisy — fires on any container with CPU limits under throttle; not actionable in homelab\n        CPUThrottlingHigh: true\n        # Expected in resource-constrained homelab; not actionable without adding hardware\n        KubeMemoryOvercommit: true\n        KubeCPUOvercommit: true\n        # Replaced with custom rule at 3x threshold (default 1.5x is too sensitive\n        # with auto-compaction; fragmentation between defrag cycles is normal)\n        etcdDatabaseHighFragmentationRatio: true\n      # Extend \"for:\" durations on upgrade-sensitive alerts to avoid transient noise\n      rules:\n        kubeProxy: false\n    customRules:\n      KubePodNotReady:\n        for: 30m\n      KubePodCrashLooping:\n        for: 30m\n      KubeContainerWaiting:\n        for: 1h\n      KubeDeploymentReplicasMismatch:\n        for: 30m\n      KubeStatefulSetReplicasMismatch:\n        for: 30m\n      KubeDeploymentRolloutStuck:\n        for: 30m\n      KubeDaemonSetRolloutStuck:\n        for: 30m\n      KubeStatefulSetUpdateNotRolledOut:\n        for: 30m\n      KubeJobFailed:\n        for: 1h\n      TargetDown:\n        for: 15m\n      # 15m default fires on transient memory spikes (Kopia backups on TrueNAS,\n      # ZFS scrubs, batch I/O). Real pressure outlasts 30m; backups don't.\n      NodeMemoryHighUtilization:\n        for: 30m\n    alertmanager:\n      alertmanagerSpec:\n        alertmanagerConfiguration:\n          name: alertmanager\n        externalUrl: https://alertmanager.${CLUSTER_DOMAIN}\n        storage:\n          volumeClaimTemplate:\n            spec:\n              storageClassName: ceph-block\n              resources:\n                requests:\n                  storage: 1Gi\n    grafana:\n      enabled: false\n      forceDeployDashboards: true\n      operator:\n        dashboardsConfigMapRefEnabled: true\n        folder: observability\n        matchLabels:\n          grafana.internal/instance: grafana\n    prometheus:\n      # thanosService:\n      #   enabled: true\n      # thanosServiceMonitor:\n      #   enabled: true\n      ## Settings affecting prometheusSpec\n      ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#prometheusspec\n      prometheusSpec:\n        priorityClassName: platform-cluster-critical\n        # REQUIRED: Cilium Hubble metrics are exposed via OpenMetrics. Prometheus Operator requires the `exemplar-storage` feature to be enabled to scrape OpenMetrics.\n        # https://docs.cilium.io/en/stable/observability/metrics/#openmetrics\n        # https://prometheus.io/docs/prometheus/latest/feature_flags/#exemplars-storage\n        enableFeatures:\n          - exemplar-storage\n          - memory-snapshot-on-shutdown\n        scrapeInterval: 1m\n        externalUrl: https://prometheus.${CLUSTER_DOMAIN}\n        podAntiAffinity: hard\n        ruleSelectorNilUsesHelmValues: false\n        serviceMonitorSelectorNilUsesHelmValues: false\n        podMonitorSelectorNilUsesHelmValues: false\n        probeSelectorNilUsesHelmValues: false\n        scrapeConfigSelectorNilUsesHelmValues: false\n        retention: 14d\n        retentionSize: 50GB\n        storageSpec:\n          volumeClaimTemplate:\n            spec:\n              storageClassName: ceph-block\n              resources:\n                requests:\n                  storage: 50Gi\n        enableAdminAPI: true\n        walCompression: true\n        resources:\n          requests:\n            cpu: 100m\n          limits:\n            memory: 2000Mi\n    additionalPrometheusRulesMap:\n      etcd-fragmentation:\n        groups:\n          - name: etcd-fragmentation\n            rules:\n              - alert: etcdDatabaseHighFragmentationRatio\n                annotations:\n                  summary: >-\n                    etcd {{ $labels.instance }} DB fragmentation is {{ $value | humanizePercentage }},\n                    indicating auto-compaction may not be working or defragmentation is overdue\n                expr: |-\n                  (last_over_time(etcd_mvcc_db_total_size_in_bytes[5m]) / last_over_time(etcd_mvcc_db_total_size_in_use_in_bytes[5m])) > 3\n                for: 30m\n                labels:\n                  severity: warning\n      oom-rules:\n        groups:\n          - name: oom\n            rules:\n              - alert: OomKilled\n                annotations:\n                  summary: >-\n                    Container {{ $labels.container }} in pod {{ $labels.namespace }}/{{ $labels.pod }}\n                    has been OOMKilled {{ $value }} times in the last 10 minutes\n                expr: |-\n                  (kube_pod_container_status_restarts_total - kube_pod_container_status_restarts_total offset 10m >= 1)\n                  and ignoring (reason) min_over_time(kube_pod_container_status_last_terminated_reason{reason=\"OOMKilled\"}[10m]) == 1\n                labels:\n                  severity: critical\n      # Maintenance signals — emit a low-severity alert when a node is\n      # cordoned/draining or when a Flux HelmRelease/Kustomization is\n      # mid-reconcile. These never email (routed to \"null\" in the\n      # AlertmanagerConfig) — their only job is to be the SOURCE side of\n      # inhibit rules so warning/info alerts sharing the same node or\n      # namespace are suppressed during planned changes. Critical alerts\n      # are intentionally NOT inhibited.\n      maintenance-signals:\n        groups:\n          - name: maintenance-signals\n            rules:\n              - alert: NodeUnderMaintenance\n                annotations:\n                  summary: >-\n                    Node {{ $labels.node }} is cordoned/unschedulable —\n                    pod and target alerts on this node are inhibited\n                expr: kube_node_spec_unschedulable == 1\n                for: 1m\n                labels:\n                  severity: info\n              # label_replace rewrites `namespace` (which is flux-system, where\n              # flux-operator runs) to the actual workload namespace, so the\n              # inhibit rule can equal on `namespace`.\n              - alert: FluxReconciliationInProgress\n                annotations:\n                  summary: >-\n                    Flux {{ $labels.kind }} {{ $labels.exported_namespace }}/{{ $labels.name }}\n                    is reconciling ({{ $labels.reason }}) — child alerts in this namespace are inhibited\n                expr: |-\n                  label_replace(\n                    flux_resource_info{kind=~\"HelmRelease|Kustomization\", ready=\"Unknown\", suspended=\"False\"} == 1,\n                    \"namespace\", \"$1\", \"exported_namespace\", \"(.+)\"\n                  )\n                for: 1m\n                labels:\n                  severity: info\n    prometheus-node-exporter:\n      fullnameOverride: node-exporter\n    kube-state-metrics:\n      fullnameOverride: kube-state-metrics\n      verticalPodAutoscaler:\n        enabled: true\n      metricLabelsAllowlist:\n        - pods=[*]\n        - deployments=[*]\n        - persistentvolumeclaims=[*]\n    # Talos binds scheduler and controller-manager to 0.0.0.0;\n    # use kube-apiserver selector since Talos labels differ from upstream\n    kubeScheduler:\n      service:\n        selector:\n          component: kube-apiserver\n    kubeControllerManager:\n      service:\n        selector:\n          component: kube-apiserver\n    # Disable kubeProxy whilst using Cilium as it's not deployed\n    kubeProxy:\n      enabled: false\n    # etcd metrics exposed on http://0.0.0.0:2381 via Talos extraArgs\n    kubeEtcd:\n      service:\n        selector:\n          component: kube-apiserver\n        port: 2381\n        targetPort: 2381\n      serviceMonitor:\n        scheme: http\n        caFile: \"\"\n        certFile: \"\"\n        keyFile: \"\"\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: alertmanager\n  namespace: observability\nspec:\n  parentRefs:\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'alertmanager.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: alertmanager-operated\n          port: 9093\n          weight: 100\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: prometheus\n  namespace: observability\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'prometheus.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: kube-prometheus-stack-prometheus\n          port: 9090\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - alertmanager-replicationsource.yaml\n  - alertmanager-volsync-externalsecret.yaml\n  - alertmanagerconfig.yaml\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n  - httproute.yaml\n  - ocirepository.yaml\n  - prometheus-replicationsource.yaml\n  - prometheus-volsync-externalsecret.yaml\n  - scrapeconfig.yaml\n  - silence-watchdog.yaml\nconfigMapGenerator:\n  - name: flux-metrics-configmap\n    files:\n      - flux-metrics.yaml=./resources/flux-metrics.yaml\ngeneratorOptions:\n  disableNameSuffixHash: true\n  annotations:\n    kustomize.toolkit.fluxcd.io/substitute: disabled\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kube-prometheus-stack\n  namespace: observability\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 85.2.0\n  url: oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/prometheus-replicationsource.yaml",
    "content": "---\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: prometheus\nspec:\n  sourcePVC: prometheus-kube-prometheus-stack-db-prometheus-kube-prometheus-stack-0\n  trigger:\n    schedule: \"0 * * * *\"\n  kopia:\n    accessModes:\n      - ReadWriteOnce\n    cacheAccessModes:\n      - ReadWriteOnce\n    cacheCapacity: 5Gi\n    cacheStorageClassName: ceph-block\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: 1000\n      runAsGroup: 2000\n      fsGroup: 2000\n    parallelism: 2\n    repository: prometheus-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ceph-block\n    volumeSnapshotClassName: csi-ceph-blockpool\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/prometheus-volsync-externalsecret.yaml",
    "content": "---\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: prometheus-volsync\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: prometheus-volsync-secret\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/resources/flux-metrics.yaml",
    "content": "---\nkube-state-metrics:\n  rbac:\n    extraRules:\n      - apiGroups:\n          - source.toolkit.fluxcd.io\n          - kustomize.toolkit.fluxcd.io\n          - helm.toolkit.fluxcd.io\n          - notification.toolkit.fluxcd.io\n        resources:\n          - gitrepositories\n          - buckets\n          - helmrepositories\n          - helmcharts\n          - ocirepositories\n          - kustomizations\n          - helmreleases\n          - alerts\n          - providers\n          - receivers\n        verbs:\n          - list\n          - watch\n  customResourceState:\n    enabled: true\n    config:\n      spec:\n        resources:\n          - groupVersionKind:\n              group: kustomize.toolkit.fluxcd.io\n              version: v1\n              kind: Kustomization\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux Kustomization resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  ready:\n                    - status\n                    - conditions\n                    - \"[type=Ready]\"\n                    - status\n                  suspended:\n                    - spec\n                    - suspend\n                  revision:\n                    - status\n                    - lastAppliedRevision\n                  source_name:\n                    - spec\n                    - sourceRef\n                    - name\n          - groupVersionKind:\n              group: helm.toolkit.fluxcd.io\n              version: v2\n              kind: HelmRelease\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux HelmRelease resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  ready:\n                    - status\n                    - conditions\n                    - \"[type=Ready]\"\n                    - status\n                  suspended:\n                    - spec\n                    - suspend\n                  revision:\n                    - status\n                    - history\n                    - \"0\"\n                    - chartVersion\n                  chart_name:\n                    - status\n                    - history\n                    - \"0\"\n                    - chartName\n                  chart_app_version:\n                    - status\n                    - history\n                    - \"0\"\n                    - appVersion\n                  chart_ref_name:\n                    - spec\n                    - chartRef\n                    - name\n                  chart_source_name:\n                    - spec\n                    - chart\n                    - spec\n                    - sourceRef\n                    - name\n          - groupVersionKind:\n              group: source.toolkit.fluxcd.io\n              version: v1\n              kind: GitRepository\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux GitRepository resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  ready:\n                    - status\n                    - conditions\n                    - \"[type=Ready]\"\n                    - status\n                  suspended:\n                    - spec\n                    - suspend\n                  revision:\n                    - status\n                    - artifact\n                    - revision\n                  url:\n                    - spec\n                    - url\n          - groupVersionKind:\n              group: source.toolkit.fluxcd.io\n              version: v1\n              kind: HelmRepository\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux HelmRepository resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  ready:\n                    - status\n                    - conditions\n                    - \"[type=Ready]\"\n                    - status\n                  suspended:\n                    - spec\n                    - suspend\n                  revision:\n                    - status\n                    - artifact\n                    - revision\n                  url:\n                    - spec\n                    - url\n          - groupVersionKind:\n              group: source.toolkit.fluxcd.io\n              version: v1\n              kind: HelmChart\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux HelmChart resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  ready:\n                    - status\n                    - conditions\n                    - \"[type=Ready]\"\n                    - status\n                  suspended:\n                    - spec\n                    - suspend\n                  revision:\n                    - status\n                    - artifact\n                    - revision\n                  chart_name:\n                    - spec\n                    - chart\n                  chart_version:\n                    - spec\n                    - version\n          - groupVersionKind:\n              group: source.toolkit.fluxcd.io\n              version: v1\n              kind: OCIRepository\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux OCIRepository resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  ready:\n                    - status\n                    - conditions\n                    - \"[type=Ready]\"\n                    - status\n                  suspended:\n                    - spec\n                    - suspend\n                  revision:\n                    - status\n                    - artifact\n                    - revision\n                  url:\n                    - spec\n                    - url\n          - groupVersionKind:\n              group: notification.toolkit.fluxcd.io\n              version: v1beta3\n              kind: Alert\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux Alert resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  suspended:\n                    - spec\n                    - suspend\n          - groupVersionKind:\n              group: notification.toolkit.fluxcd.io\n              version: v1beta3\n              kind: Provider\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux Provider resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  suspended:\n                    - spec\n                    - suspend\n          - groupVersionKind:\n              group: notification.toolkit.fluxcd.io\n              version: v1\n              kind: Receiver\n            metricNamePrefix: gotk\n            metrics:\n              - name: resource_info\n                help: The current state of a Flux Receiver resource.\n                each:\n                  type: Info\n                  info:\n                    labelsFromPath:\n                      name:\n                        - metadata\n                        - name\n                labelsFromPath:\n                  exported_namespace:\n                    - metadata\n                    - namespace\n                  ready:\n                    - status\n                    - conditions\n                    - \"[type=Ready]\"\n                    - status\n                  suspended:\n                    - spec\n                    - suspend\n                  webhook_path:\n                    - status\n                    - webhookPath\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/scrapeconfig.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/scrapeconfig_v1alpha1.json\napiVersion: monitoring.coreos.com/v1alpha1\nkind: ScrapeConfig\nmetadata:\n  name: node-exporter\nspec:\n  staticConfigs:\n    - targets:\n        - expanse.internal:9100\n  metricsPath: /metrics\n  relabelings:\n    - action: replace\n      targetLabel: job\n      replacement: node-exporter\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/scrapeconfig_v1alpha1.json\napiVersion: monitoring.coreos.com/v1alpha1\nkind: ScrapeConfig\nmetadata:\n  name: smartctl-exporter\nspec:\n  staticConfigs:\n    - targets:\n        - expanse.internal:9633\n  metricsPath: /metrics\n  relabelings:\n    - action: replace\n      targetLabel: job\n      replacement: smartctl-exporter\n---\n# # yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/scrapeconfig_v1alpha1.json\napiVersion: monitoring.coreos.com/v1alpha1\nkind: ScrapeConfig\nmetadata:\n  name: jetkvm\nspec:\n  staticConfigs:\n    - targets:\n        - jetkvm-01.internal\n        - jetkvm-02.internal\n        - jetkvm-03.internal\n  metricsPath: /metrics\n  relabelings:\n    - action: replace\n      targetLabel: job\n      replacement: jetkvm\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/app/silence-watchdog.yaml",
    "content": "---\napiVersion: observability.giantswarm.io/v1alpha2\nkind: Silence\nmetadata:\n  name: watchdog\n  namespace: observability\nspec:\n  matchers:\n    - name: alertname\n      value: Watchdog\n      matchType: \"=\"\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kube-prometheus-stack/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kube-prometheus-stack\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/kube-prometheus-stack/app\"\n  wait: true\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n    - name: rook-ceph-cluster\n      namespace: rook-ceph\n    - name: volsync\n      namespace: volsync-system\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: kube-prometheus-stack\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: observability\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/loki/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app loki\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: loki\n  values:\n    singleBinary:\n      replicas: 1\n      nodeSelector:\n        openebs.io/storage: \"true\"\n        kubernetes.io/arch: arm64\n    loki:\n      storage:\n        type: filesystem\n      auth_enabled: false\n      commonConfig:\n        replication_factor: 1\n      limits_config:\n        retention_period: 14d\n        enforce_metric_name: false\n        reject_old_samples: true\n        reject_old_samples_max_age: 168h\n        max_cache_freshness_per_query: 10m\n        split_queries_by_interval: 15m\n        ingestion_rate_mb: 8\n        ingestion_burst_size_mb: 16\n        shard_streams:\n          enabled: true\n      compactor:\n        working_directory: /var/loki/boltdb-shipper-compactor\n        shared_store: filesystem\n        compaction_interval: 10m\n        retention_enabled: true\n        retention_delete_delay: 2h\n        retention_delete_worker_count: 150\n      ingester:\n        max_chunk_age: 1h\n      analytics:\n        reporting_enabled: false\n    test:\n      enabled: false\n    read:\n      replicas: 1\n      # persistence:\n      #   storageClass: cstor-replica-raspberry-pi-pool\n    write:\n      replicas: 1\n      # persistence:\n      #   storageClass: cstor-replica-raspberry-pi-pool\n    backend:\n      replicas: 1\n      # persistence:\n      #   storageClass: cstor-replica-raspberry-pi-pool\n    monitoring:\n      dashboards:\n        annotations:\n          grafana_folder: Loki\n      selfMonitoring:\n        enabled: false\n        grafanaAgent:\n          installOperator: false\n      lokiCanary:\n        enabled: false\n      # structuredConfig:\n      #   memberlist:\n      #     join_members: [\"loki-memberlist\"]\n"
  },
  {
    "path": "kubernetes/apps/base/observability/loki/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/loki/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: loki\n  namespace: observability\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 6.30.0\n  url: oci://ghcr.io/home-operations/charts-mirror/loki\n"
  },
  {
    "path": "kubernetes/apps/base/observability/loki/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: loki\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/loki/app\"\n  wait: false\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: loki\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: observability\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/observability/otel/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: otel-operator\n  namespace: observability\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: opentelemetry-operator\n"
  },
  {
    "path": "kubernetes/apps/base/observability/otel/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/otel/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: opentelemetry-operator\n  namespace: observability\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.113.1\n  url: oci://ghcr.io/open-telemetry/opentelemetry-helm-charts/opentelemetry-operator\n"
  },
  {
    "path": "kubernetes/apps/base/observability/otel/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: otel\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/otel/app\"\n  wait: false\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: otel\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/silence-operator/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: silence-operator\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: silence-operator\n  values:\n    alertmanagerAddress: http://kube-prometheus-stack-alertmanager.observability.svc.cluster.local:9093\n    networkPolicy:\n      enabled: false\n"
  },
  {
    "path": "kubernetes/apps/base/observability/silence-operator/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/silence-operator/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: silence-operator\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.20.1\n  url: oci://gsoci.azurecr.io/charts/giantswarm/silence-operator\n"
  },
  {
    "path": "kubernetes/apps/base/observability/silence-operator/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: silence-operator\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/silence-operator/app\"\n  wait: true\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: silence-operator\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/observability/vpa/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: vpa\nspec:\n  interval: 1h\n  chart:\n    spec:\n      chart: vpa\n      version: 4.11.0\n      sourceRef:\n        kind: HelmRepository\n        name: fairwinds-charts\n        namespace: flux-system\n      interval: 10m\n  values:\n    recommender:\n      extraArgs:\n        storage: prometheus\n        prometheus-address: |-\n          http://prometheus-operated.observability.svc.cluster.local:9090\n"
  },
  {
    "path": "kubernetes/apps/base/observability/vpa/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/observability/vpa/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: vpa\n  namespace: observability\nspec:\n  path: \"./apps/base/observability/vpa/app\"\n  wait: false\n  targetNamespace: observability\n  sourceRef:\n    kind: ExternalArtifact\n    name: vpa\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/preview-system/app/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: github-auth\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: github-auth\n    template:\n      data:\n        username: xunholy\n        password: \"{{ .FLUX_GITHUB_TOKEN }}\"\n  dataFrom:\n    - extract:\n        key: flux\n"
  },
  {
    "path": "kubernetes/apps/base/preview-system/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - externalsecret.yaml\n  - resourcesetinputprovider.yaml\n  - resourceset.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/preview-system/app/resourceset.yaml",
    "content": "---\napiVersion: fluxcd.controlplane.io/v1\nkind: ResourceSet\nmetadata:\n  name: emberstone-portal-preview\nspec:\n  inputsFrom:\n    - kind: ResourceSetInputProvider\n      name: github-pr-previews\n  resources:\n    # Namespace per PR\n    - apiVersion: v1\n      kind: Namespace\n      metadata:\n        name: preview-pr-<< inputs.id >>\n        labels:\n          pod-security.kubernetes.io/enforce: baseline\n          preview: \"true\"\n        annotations:\n          preview.fluxcd.io/pr: << inputs.id | quote >>\n          preview.fluxcd.io/branch: << inputs.branch | quote >>\n          preview.fluxcd.io/author: << inputs.author | quote >>\n    # ResourceQuota to limit preview resource usage\n    - apiVersion: v1\n      kind: ResourceQuota\n      metadata:\n        name: preview-quota\n        namespace: preview-pr-<< inputs.id >>\n      spec:\n        hard:\n          requests.cpu: \"500m\"\n          requests.memory: \"512Mi\"\n          limits.memory: \"1Gi\"\n          pods: \"10\"\n    # Git source at the PR commit SHA\n    - apiVersion: source.toolkit.fluxcd.io/v1\n      kind: GitRepository\n      metadata:\n        name: pr-<< inputs.id >>\n        namespace: preview-pr-<< inputs.id >>\n      spec:\n        interval: 5m\n        url: https://github.com/xunholy/k8s-gitops\n        ref:\n          commit: << inputs.sha >>\n        secretRef:\n          name: github-auth\n    # Copy the GitHub auth secret into the preview namespace\n    - apiVersion: external-secrets.io/v1\n      kind: ExternalSecret\n      metadata:\n        name: github-auth\n        namespace: preview-pr-<< inputs.id >>\n      spec:\n        secretStoreRef:\n          kind: ClusterSecretStore\n          name: onepassword\n        target:\n          name: github-auth\n          template:\n            data:\n              username: xunholy\n              password: \"{{ .FLUX_GITHUB_TOKEN }}\"\n        dataFrom:\n          - extract:\n              key: flux\n    # Kustomization deploying emberstone-portal from the PR branch\n    - apiVersion: kustomize.toolkit.fluxcd.io/v1\n      kind: Kustomization\n      metadata:\n        name: emberstone-portal-pr-<< inputs.id >>\n        namespace: preview-pr-<< inputs.id >>\n        labels:\n          gitops.owncloud.ai/defaults: disabled\n        annotations:\n          event.toolkit.fluxcd.io/change_request: << inputs.id | quote >>\n          event.toolkit.fluxcd.io/commit: << inputs.sha | quote >>\n      spec:\n        interval: 5m\n        retryInterval: 1m\n        timeout: 10m\n        prune: true\n        wait: true\n        path: ./kubernetes/apps/base/game-servers/emberstone-portal/app\n        sourceRef:\n          kind: GitRepository\n          name: pr-<< inputs.id >>\n        targetNamespace: preview-pr-<< inputs.id >>\n        postBuild:\n          substitute:\n            CLUSTER_TIMEZONE: \"Australia/Melbourne\"\n            CLUSTER_DOMAIN: \"owncloud.ai\"\n    # Post preview URL as a PR comment\n    - apiVersion: batch/v1\n      kind: Job\n      metadata:\n        name: preview-comment\n        namespace: preview-pr-<< inputs.id >>\n      spec:\n        ttlSecondsAfterFinished: 300\n        backoffLimit: 3\n        template:\n          spec:\n            restartPolicy: Never\n            containers:\n              - name: comment\n                image: curlimages/curl:8.20.0\n                resources:\n                  requests:\n                    cpu: 10m\n                    memory: 32Mi\n                  limits:\n                    memory: 64Mi\n                command: [\"sh\", \"-c\"]\n                args:\n                  - |\n                    curl -sf -X POST \\\n                      -H \"Authorization: token $(cat /secrets/password)\" \\\n                      -H \"Accept: application/vnd.github+json\" \\\n                      \"https://api.github.com/repos/xunholy/k8s-gitops/issues/<< inputs.id >>/comments\" \\\n                      -d \"{\\\"body\\\":\\\"## Preview Environment\\\\n\\\\n| | |\\\\n|---|---|\\\\n| **URL** | [https://<< inputs.id >>.preview.owncloud.ai](https://<< inputs.id >>.preview.owncloud.ai) |\\\\n| **Branch** | \\`<< inputs.branch >>\\` |\\\\n| **Commit** | \\`$(echo '<< inputs.sha >>' | cut -c1-7)\\` |\\\\n\\\\n> This preview will be automatically destroyed when the PR is closed or the label is removed.\\\"}\"\n                volumeMounts:\n                  - name: github-auth\n                    mountPath: /secrets\n                    readOnly: true\n            volumes:\n              - name: github-auth\n                secret:\n                  secretName: github-auth\n    # HTTPRoute for internal-only preview access at {id}.preview.owncloud.ai\n    - apiVersion: gateway.networking.k8s.io/v1\n      kind: HTTPRoute\n      metadata:\n        name: emberstone-portal-preview\n        namespace: preview-pr-<< inputs.id >>\n      spec:\n        parentRefs:\n          - name: envoy-internal\n            namespace: network-system\n            sectionName: https\n        hostnames:\n          - << inputs.id >>.preview.owncloud.ai\n        rules:\n          - backendRefs:\n              - name: emberstone-portal\n                port: 80\n                weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/preview-system/app/resourcesetinputprovider.yaml",
    "content": "---\napiVersion: fluxcd.controlplane.io/v1\nkind: ResourceSetInputProvider\nmetadata:\n  name: github-pr-previews\n  annotations:\n    fluxcd.controlplane.io/reconcileEvery: \"5m\"\nspec:\n  type: GitHubPullRequest\n  url: https://github.com/xunholy/k8s-gitops\n  secretRef:\n    name: github-auth\n  filter:\n    labels:\n      - \"deploy/preview\"\n    limit: 3\n"
  },
  {
    "path": "kubernetes/apps/base/preview-system/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: preview-system\n  namespace: preview-system\nspec:\n  dependsOn:\n    - name: onepassword\n      namespace: external-secrets\n  path: \"./apps/base/preview-system/app\"\n  wait: true\n  targetNamespace: preview-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: preview-system\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/preview-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: preview-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/preview-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: preview-system\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/audit: baseline\n    pod-security.kubernetes.io/enforce: baseline\n    pod-security.kubernetes.io/warn: baseline\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: rook-ceph\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: rook-ceph\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: ceph-cluster\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/2842/revisions/18/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: ceph-osd\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/5336/revisions/9/download\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: ceph-pools\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/5342/revisions/9/download\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app rook-ceph\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: rook-ceph\n  valuesFrom:\n    - kind: ConfigMap\n      name: rook-ceph-values\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n  - ocirepository.yaml\n  - pdb.yaml\n\nconfigMapGenerator:\n  - name: rook-ceph-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: rook-ceph\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: v1.19.5\n  url: oci://ghcr.io/rook/rook-ceph\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/app/pdb.yaml",
    "content": "---\napiVersion: policy/v1\nkind: PodDisruptionBudget\nmetadata:\n  name: rook-ceph-operator\nspec:\n  minAvailable: 1\n  selector:\n    matchLabels:\n      app: rook-ceph-operator\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/app/values.yaml",
    "content": "priorityClassName: platform-cluster-critical\ncsi:\n  cephFSKernelMountOptions: ms_mode=prefer-crc\n  enableLiveness: true\n  provisionerPriorityClassName: platform-cluster-critical\n  pluginPriorityClassName: platform-node-critical\n  serviceMonitor:\n    enabled: true\nimage:\n  repository: ghcr.io/rook/ceph\nmonitoring:\n  enabled: true\nresources:\n  requests:\n    memory: 128Mi # unchangable\n    cpu: 100m # unchangable\n  limits: {}\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/cluster/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app rook-ceph-cluster\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: rook-ceph-cluster\n  valuesFrom:\n    - kind: ConfigMap\n      name: rook-ceph-cluster-values\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/cluster/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n\nconfigMapGenerator:\n  - name: rook-ceph-cluster-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/cluster/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/cluster/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: rook-ceph-cluster\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: v1.19.5\n  url: oci://ghcr.io/rook/rook-ceph-cluster\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/cluster/values.yaml",
    "content": "monitoring:\n  enabled: true\n  createPrometheusRules: true\ntoolbox:\n  enabled: true\ncephClusterSpec:\n  cephConfig:\n    global:\n      bdev_enable_discard: \"true\" # quote\n      bdev_async_discard_threads: \"1\" # quote\n      osd_class_update_on_start: \"false\" # quote\n      device_failure_prediction_mode: local # requires mgr module\n  cleanupPolicy:\n    wipeDevicesFromOtherClusters: true\n  crashCollector:\n    disable: false\n  csi:\n    readAffinity:\n      enabled: true\n  priorityClassNames:\n    mon: platform-node-critical\n    osd: platform-node-critical\n    mgr: platform-cluster-critical\n  resources:\n    mon:\n      requests:\n        cpu: 250m\n        memory: 1Gi\n      limits:\n        memory: 2Gi\n    mgr:\n      requests:\n        cpu: 250m\n        memory: 512Mi\n      limits:\n        memory: 2Gi\n    osd:\n      # Request matches default osd_memory_target (4 GiB); limit gives headroom for\n      # backfill/recovery and bootstrap, where Ceph routinely doubles working set.\n      requests:\n        cpu: 500m\n        memory: 4Gi\n      limits:\n        memory: 8Gi\n  dashboard:\n    enabled: true\n    urlPrefix: /\n    ssl: false\n    prometheusEndpoint: http://prometheus-operated.observability.svc.cluster.local:9090\n  mgr:\n    modules:\n      - name: diskprediction_local\n        enabled: true\n      - name: insights\n        enabled: true\n      - name: pg_autoscaler\n        enabled: true\n      - name: rook\n        enabled: true\n  network:\n    connections:\n      requireMsgr2: true\n  storage:\n    useAllNodes: true\n    useAllDevices: false\n    devicePathFilter: /dev/disk/by-id/nvme-Micron_7450_MTFDKBA960TFR_.*\n    config:\n      osdsPerDevice: \"1\"\ncephBlockPools:\n  - name: ceph-blockpool\n    spec:\n      failureDomain: host\n      replicated:\n        size: 3\n    storageClass:\n      enabled: true\n      name: ceph-block\n      isDefault: true\n      reclaimPolicy: Delete\n      allowVolumeExpansion: true\n      volumeBindingMode: Immediate\n      mountOptions:\n        - discard\n      parameters:\n        compression_mode: aggressive\n        compression_algorithm: zstd\n        imageFormat: \"2\"\n        imageFeatures: layering,fast-diff,object-map,deep-flatten,exclusive-lock\n        csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner\n        csi.storage.k8s.io/provisioner-secret-namespace: \"{{ .Release.Namespace }}\"\n        csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner\n        csi.storage.k8s.io/controller-expand-secret-namespace: \"{{ .Release.Namespace }}\"\n        csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node\n        csi.storage.k8s.io/node-stage-secret-namespace: \"{{ .Release.Namespace }}\"\n        csi.storage.k8s.io/fstype: ext4\ncephBlockPoolsVolumeSnapshotClass:\n  enabled: true\n  name: csi-ceph-blockpool\n  isDefault: false\n  deletionPolicy: Delete\ncephFileSystems:\n  - name: &cephFileSystemName ceph-filesystem\n    spec:\n      metadataPool:\n        replicated:\n          size: 3\n      dataPools:\n        - failureDomain: host\n          replicated:\n            size: 3\n          name: data0\n      metadataServer:\n        activeCount: 1\n        activeStandby: true\n        priorityClassName: platform-cluster-critical\n        placement:\n          topologySpreadConstraints:\n            - maxSkew: 1\n              topologyKey: kubernetes.io/hostname\n              whenUnsatisfiable: DoNotSchedule\n              labelSelector:\n                matchLabels:\n                  app.kubernetes.io/name: ceph-mds\n                  app.kubernetes.io/part-of: *cephFileSystemName\n        resources:\n          requests:\n            cpu: 100m\n            memory: 1Gi\n          limits:\n            memory: 4Gi\n    storageClass:\n      enabled: true\n      isDefault: false\n      name: ceph-filesystem\n      pool: data0\n      reclaimPolicy: Delete\n      allowVolumeExpansion: true\n      volumeBindingMode: Immediate\n      parameters:\n        csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner\n        csi.storage.k8s.io/provisioner-secret-namespace: \"{{ .Release.Namespace }}\"\n        csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner\n        csi.storage.k8s.io/controller-expand-secret-namespace: \"{{ .Release.Namespace }}\"\n        csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node\n        csi.storage.k8s.io/node-stage-secret-namespace: \"{{ .Release.Namespace }}\"\n        csi.storage.k8s.io/fstype: ext4\ncephFileSystemVolumeSnapshotClass:\n  enabled: true\n  name: csi-ceph-filesystem\n  isDefault: false\n  deletionPolicy: Delete\ncephObjectStores: []\n"
  },
  {
    "path": "kubernetes/apps/base/rook-ceph/rook-ceph/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: rook-ceph\n  namespace: rook-ceph\nspec:\n  path: \"./apps/base/rook-ceph/rook-ceph/app\"\n  wait: true\n  dependsOn:\n    - name: snapshot-controller\n      namespace: kube-system\n  targetNamespace: rook-ceph\n  sourceRef:\n    kind: ExternalArtifact\n    name: rook-ceph\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: rook-ceph-cluster\n  namespace: rook-ceph\nspec:\n  path: \"./apps/base/rook-ceph/rook-ceph/cluster\"\n  wait: true\n  targetNamespace: rook-ceph\n  dependsOn:\n    - name: rook-ceph\n      namespace: rook-ceph\n  # - name: volsync\n  #   namespace: volsync-system\n\n  sourceRef:\n    kind: ExternalArtifact\n    name: rook-ceph-cluster\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/crowdsec/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: crowdsec\n  namespace: security-system\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: crowdsec\n      version: 0.24.0\n      sourceRef:\n        kind: HelmRepository\n        name: crowdsec-charts\n        namespace: flux-system\n      interval: 10m\n  values:\n    container_runtime: containerd\n    lapi:\n      affinity:\n        nodeAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            nodeSelectorTerms:\n              - matchExpressions:\n                  - key: kubernetes.io/arch\n                    operator: In\n                    values:\n                      - amd64\n      dashboard:\n        # TODO: No arm64 images, raise a GH issue\n        enabled: false\n      metrics:\n        enabled: true\n        serviceMonitor:\n          enabled: true\n      persistentVolume:\n        data:\n          enabled: false\n          accessModes:\n            - ReadWriteOnce\n          # storageClassName: \"cstor-replica-raspberry-pi-pool\"\n          size: 1Gi\n        config:\n          enabled: true\n          accessModes:\n            - ReadWriteOnce\n          # storageClassName: \"cstor-replica-raspberry-pi-pool\"\n          size: 100Mi\n    agent:\n      acquisition:\n        - namespace: nginx-ingress\n          podName: ingress-nginx-controller-*\n          program: nginx\n      metrics:\n        enabled: true\n        serviceMonitor:\n          enabled: true\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/crowdsec/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: crowdsec\n  namespace: security-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'metabase.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: crowdsec-service\n          port: 3000\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/crowdsec/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/crowdsec/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: crowdsec\n  namespace: flux-system\nspec:\n  path: \"./apps/base/security-system/crowdsec/app\"\n  wait: true\n  targetNamespace: security-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: crowdsec\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: falco\n  namespace: security-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: falco\n  values:\n    ebpf:\n      enabled: true\n    affinity:\n      nodeAffinity:\n        requiredDuringSchedulingIgnoredDuringExecution:\n          nodeSelectorTerms:\n            - matchExpressions:\n                - key: kubernetes.io/arch\n                  operator: In\n                  values:\n                    - amd64\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: falco\n  namespace: security-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 8.0.5\n  url: oci://ghcr.io/falcosecurity/charts/falco\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: falco\n  namespace: flux-system\nspec:\n  path: \"./apps/base/security-system/falco/app\"\n  wait: true\n  targetNamespace: security-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: falco\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco-exporter/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: falco-exporter\n  namespace: security-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: falco-exporter\n  values:\n    affinity:\n      nodeAffinity:\n        requiredDuringSchedulingIgnoredDuringExecution:\n          nodeSelectorTerms:\n            - matchExpressions:\n                - key: kubernetes.io/arch\n                  operator: In\n                  values:\n                    - amd64\n    serviceMonitor:\n      enabled: true\n    grafanaDashboard:\n      enabled: false\n      namespace: default\n    prometheusRules:\n      enabled: false\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco-exporter/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco-exporter/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: falco-exporter\n  namespace: security-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.12.2\n  url: oci://ghcr.io/falcosecurity/charts/falco-exporter\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/falco-exporter/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: falco-exporter\n  namespace: flux-system\nspec:\n  path: \"./apps/base/security-system/falco-exporter/app\"\n  wait: true\n  targetNamespace: security-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: falco-exporter\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/gatekeeper/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: gatekeeper-dashboard\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  url: https://grafana.com/api/dashboards/15763/revisions/1/download\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/gatekeeper/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: gatekeeper\n  namespace: security-system\nspec:\n  interval: 5m\n  chart:\n    spec:\n      chart: gatekeeper\n      version: 3.22.2\n      sourceRef:\n        kind: HelmRepository\n        name: gatekeeper-charts\n        namespace: flux-system\n      interval: 10m\n  values:\n    psp:\n      enabled: false\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/gatekeeper/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/gatekeeper/app/podmonitor.yaml",
    "content": "# This will scrap for both audit and controller-manager as the label is consistent in both pods.\n---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/podmonitor_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PodMonitor\nmetadata:\n  name: gatekeeper\n  namespace: gatekeeper-system\nspec:\n  namespaceSelector:\n    matchNames:\n      - gatekeeper-system\n  selector:\n    matchLabels:\n      gatekeeper.sh/system: 'yes'\n  podMetricsEndpoints:\n    - port: metrics\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/gatekeeper/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: gatekeeper\n  namespace: flux-system\nspec:\n  path: \"./apps/base/security-system/gatekeeper/app\"\n  wait: true\n  targetNamespace: security-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: gatekeeper\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: security-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/kyverno/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: kyverno\n  namespace: security-system\nspec:\n  interval: 1h\n  chartRef:\n    kind: OCIRepository\n    name: kyverno\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/kyverno/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - ocirepository.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/kyverno/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: kyverno\n  namespace: security-system\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 3.6.1\n  url: oci://ghcr.io/kyverno/kyverno\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/kyverno/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kyverno\n  namespace: flux-system\nspec:\n  path: \"./apps/base/security-system/kyverno/app\"\n  wait: true\n  targetNamespace: security-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kyverno\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/security-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: security-system\n  labels:\n    goldilocks.fairwinds.com/enabled: \"true\"\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/kopia/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app kopia\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: app-template\n    namespace: flux-system\n  valuesFrom:\n    - kind: ConfigMap\n      name: kopia-values\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/kopia/app/httproute.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: kopia\n  namespace: volsync-system\nspec:\n  parentRefs:\n    - name: envoy-external\n      namespace: network-system\n      sectionName: https\n    - name: envoy-internal\n      namespace: network-system\n      sectionName: https\n  hostnames:\n    - 'kopia.${CLUSTER_DOMAIN}'\n  rules:\n    - backendRefs:\n        - name: kopia\n          port: 80\n          weight: 100\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/kopia/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n  - httproute.yaml\n\nconfigMapGenerator:\n  - name: kopia-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/kopia/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/kopia/app/values.yaml",
    "content": "controllers:\n  kopia:\n    containers:\n      app:\n        image:\n          repository: ghcr.io/home-operations/kopia\n          tag: 0.23.0@sha256:76865b421548b1d7bb26a8268f0f0bc828be4eec3f8d8b9c8ece991c99878f94\n        env:\n          KOPIA_WEB_ENABLED: true\n          KOPIA_WEB_PORT: &port 80\n          TZ: ${CLUSTER_TIMEZONE}\n        envFrom:\n          - secretRef:\n              name: kopia-secret\n        args:\n          - --without-password\n        probes:\n          liveness: &probes\n            enabled: true\n            custom: true\n            spec:\n              httpGet:\n                path: /\n                port: *port\n              initialDelaySeconds: 0\n              periodSeconds: 10\n              timeoutSeconds: 1\n              failureThreshold: 3\n          readiness: *probes\n        securityContext:\n          allowPrivilegeEscalation: false\n          readOnlyRootFilesystem: true\n          capabilities: { drop: [\"ALL\"] }\n        resources:\n          requests:\n            cpu: 10m\n          limits:\n            memory: 1Gi\ndefaultPodOptions:\n  securityContext:\n    runAsNonRoot: true\n    runAsUser: 1000\n    runAsGroup: 1000\n    fsGroup: 1000\n    fsGroupChangePolicy: OnRootMismatch\nservice:\n  app:\n    ports:\n      http:\n        port: *port\nconfigMaps:\n  config:\n    data:\n      repository.config: |-\n        {\n          \"storage\": {\n            \"type\": \"filesystem\",\n            \"config\": {\n              \"path\": \"/repository\"\n            }\n          },\n          \"hostname\": \"volsync.{{ .Release.Namespace }}.svc.cluster.local\",\n          \"username\": \"volsync\",\n          \"description\": \"volsync\",\n          \"enableActions\": false\n        }\npersistence:\n  config-file:\n    type: configMap\n    identifier: config\n    globalMounts:\n      - path: /config/repository.config\n        subPath: repository.config\n  repository:\n    type: nfs\n    server: ${CLUSTER_NFS_SERVER}\n    path: /mnt/tank/volsynckopia\n    globalMounts:\n      - path: /repository\n  tmpfs:\n    type: emptyDir\n    advancedMounts:\n      kopia:\n        app:\n          - path: /config/cache\n            subPath: cache\n          - path: /config/logs\n            subPath: logs\n          - path: /tmp\n            subPath: tmp\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/kopia/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: kopia\n  namespace: volsync-system\nspec:\n  path: \"./apps/base/volsync-system/kopia/app\"\n  wait: true\n  targetNamespace: volsync-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: kopia\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: volsync-system\n\ncomponents:\n  - ../../../components/common\n\nresources:\n  - namespace.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/namespace.yaml",
    "content": "---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: volsync-system\n  labels:\n    kustomize.toolkit.fluxcd.io/prune: disabled\n    pod-security.kubernetes.io/enforce: privileged\n    pod-security.kubernetes.io/warn: privileged\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/grafanadashboard.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/grafana.integreatly.org/grafanadashboard_v1beta1.json\napiVersion: grafana.integreatly.org/v1beta1\nkind: GrafanaDashboard\nmetadata:\n  name: volsync\nspec:\n  allowCrossNamespaceImport: true\n  instanceSelector:\n    matchLabels:\n      grafana.internal/instance: grafana\n  datasources:\n    - datasourceName: prometheus\n      inputName: DS_PROMETHEUS\n  envs:\n    - name: VAR_REPLICATIONDESTNAME\n      value: .*-dst\n  url: https://grafana.com/api/dashboards/21356/revisions/3/download\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app volsync\nspec:\n  interval: 5m\n  chartRef:\n    kind: OCIRepository\n    name: volsync\n  valuesFrom:\n    - kind: ConfigMap\n      name: volsync-values\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - grafanadashboard.yaml\n  - helmrelease.yaml\n  - mutatingadmissionpolicy.yaml\n  - ocirepository.yaml\n  - prometheusrule.yaml\n\nconfigMapGenerator:\n  - name: volsync-values\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/mutatingadmissionpolicy.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.0/mutatingadmissionpolicybinding-admissionregistration-v1beta1.json\napiVersion: admissionregistration.k8s.io/v1beta1\nkind: MutatingAdmissionPolicyBinding\nmetadata:\n  name: volsync-mover-jitter\nspec:\n  policyName: volsync-mover-jitter\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.0/mutatingadmissionpolicy-admissionregistration-v1beta1.json\napiVersion: admissionregistration.k8s.io/v1beta1\nkind: MutatingAdmissionPolicy\nmetadata:\n  name: volsync-mover-jitter\nspec:\n  matchConstraints:\n    resourceRules:\n      - apiGroups:\n          - batch\n        apiVersions:\n          - v1\n        operations:\n          - CREATE\n          - UPDATE\n        resources:\n          - jobs\n  matchConditions:\n    - name: has-volsync-job-name-prefix\n      expression: >-\n        object.metadata.name.startsWith(\"volsync-src-\")\n    - name: has-volsync-created-by-labels\n      expression: >-\n        object.metadata.?labels[\"app.kubernetes.io/created-by\"].orValue(\"\") == \"volsync\"\n  failurePolicy: Fail\n  reinvocationPolicy: IfNeeded\n  mutations:\n    - patchType: JSONPatch\n      jsonPatch:\n        expression: >-\n          [\n            JSONPatch{\n              op: \"add\", path: \"/spec/template/spec/initContainers\",\n              value: []\n            },\n            JSONPatch{\n              op: \"add\", path: \"/spec/template/spec/initContainers/-\",\n              value: Object.spec.template.spec.initContainers{\n                name: \"jitter\",\n                image: \"ghcr.io/home-operations/busybox:1.37.0@sha256:026ed7273270ec08f6902b4ae8334c23b473e5394bec3bbbdbfe580c710d50bc\",\n                imagePullPolicy: \"IfNotPresent\",\n                command: [\"sh\", \"-c\", \"sleep $(shuf -i 0-30 -n 1)\"]\n              }\n            }\n          ]\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.0/mutatingadmissionpolicybinding-admissionregistration-v1beta1.json\napiVersion: admissionregistration.k8s.io/v1beta1\nkind: MutatingAdmissionPolicyBinding\nmetadata:\n  name: volsync-mover-nfs\nspec:\n  policyName: volsync-mover-nfs\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.0/mutatingadmissionpolicy-admissionregistration-v1beta1.json\napiVersion: admissionregistration.k8s.io/v1beta1\nkind: MutatingAdmissionPolicy\nmetadata:\n  name: volsync-mover-nfs\nspec:\n  matchConstraints:\n    resourceRules:\n      - apiGroups:\n          - batch\n        apiVersions:\n          - v1\n        operations:\n          - CREATE\n          - UPDATE\n        resources:\n          - jobs\n  matchConditions:\n    - name: has-volsync-job-name-prefix\n      expression: >-\n        object.metadata.name.startsWith(\"volsync-\")\n    - name: has-volsync-created-by-labels\n      expression: >-\n        object.metadata.?labels[\"app.kubernetes.io/created-by\"].orValue(\"\") == \"volsync\"\n    - name: repository-volume-does-not-exist\n      expression: >-\n        !has(object.spec.template.spec.volumes) ||\n        !object.spec.template.spec.volumes.exists(item, item.name == \"repository\")\n  failurePolicy: Fail\n  reinvocationPolicy: IfNeeded\n  mutations:\n    - patchType: JSONPatch\n      jsonPatch:\n        expression: >-\n          [\n            JSONPatch{\n              op: \"add\", path: \"/spec/template/spec/containers/0/volumeMounts/-\",\n              value: Object.spec.template.spec.containers.volumeMounts{\n                name: \"repository\",\n                mountPath: \"/repository\"\n              }\n            },\n            JSONPatch{\n              op: \"add\", path: \"/spec/template/spec/volumes/-\",\n              value: Object.spec.template.spec.volumes{\n                name: \"repository\",\n                nfs: Object.spec.template.spec.volumes.nfs{\n                  server: \"expanse.internal\",\n                  path: \"/mnt/tank/volsynckopia\"\n                }\n              }\n            }\n          ]\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/ocirepository.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json\napiVersion: source.toolkit.fluxcd.io/v1\nkind: OCIRepository\nmetadata:\n  name: volsync\nspec:\n  interval: 5m\n  layerSelector:\n    mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip\n    operation: copy\n  ref:\n    tag: 0.18.5\n  url: oci://ghcr.io/home-operations/charts-mirror/volsync-perfectra1n\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/prometheusrule.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/prometheusrule_v1.json\napiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  name: volsync\nspec:\n  groups:\n    - name: volsync.rules\n      rules:\n        - alert: VolSyncComponentAbsent\n          expr: |-\n            absent(up{job=\"volsync-metrics\"})\n          annotations:\n            summary: >-\n              VolSync component has disappeared from Prometheus target discovery\n          for: 1h\n          labels:\n            severity: warning\n\n        - alert: VolSyncVolumeOutOfSync\n          expr: |-\n            volsync_volume_out_of_sync == 1\n          annotations:\n            summary: >-\n              {{ $labels.obj_namespace }}/{{ $labels.obj_name }} volume is out of sync\n          for: 6h\n          labels:\n            severity: warning\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/app/values.yaml",
    "content": "fullnameOverride: volsync # Required for volsync-perfectra1n fork\nimage: &image\n  repository: ghcr.io/perfectra1n/volsync\n  tag: v0.17.11\nkopia: *image\nrclone: *image\nrestic: *image\nrsync: *image\nrsync-tls: *image\nsyncthing: *image\nmanageCRDs: true\nmetrics:\n  disableAuth: true\npodSecurityContext:\n  runAsNonRoot: true\n  runAsUser: 1000\n  runAsGroup: 1000\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: volsync\n  namespace: volsync-system\nspec:\n  path: \"./apps/base/volsync-system/volsync/app\"\n  wait: true\n  targetNamespace: volsync-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: volsync\n    namespace: flux-system\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: volsync-maintenance\n  namespace: volsync-system\nspec:\n  path: \"./apps/base/volsync-system/volsync/maintenance\"\n  wait: true\n  targetNamespace: volsync-system\n  dependsOn:\n    - name: volsync\n      namespace: volsync-system\n  sourceRef:\n    kind: ExternalArtifact\n    name: volsync-maintenance\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/maintenance/kopiamaintenance.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/volsync.backube/kopiamaintenance_v1alpha1.json\napiVersion: volsync.backube/v1alpha1\nkind: KopiaMaintenance\nmetadata:\n  name: daily\n  namespace: volsync\nspec:\n  enabled: true\n  trigger:\n    schedule: 0 */8 * * *\n  repository:\n    repository: volsync-maintenance-secret\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/maintenance/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: volsync-system\n\nresources:\n  - ./kopiamaintenance.yaml\n  - ./mutatingadmissionpolicy.yaml\n"
  },
  {
    "path": "kubernetes/apps/base/volsync-system/volsync/maintenance/mutatingadmissionpolicy.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.0/mutatingadmissionpolicybinding-admissionregistration-v1beta1.json\napiVersion: admissionregistration.k8s.io/v1beta1\nkind: MutatingAdmissionPolicyBinding\nmetadata:\n  name: kopia-maintenance-nfs\nspec:\n  policyName: kopia-maintenance-nfs\n---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.0/mutatingadmissionpolicy-admissionregistration-v1beta1.json\napiVersion: admissionregistration.k8s.io/v1beta1\nkind: MutatingAdmissionPolicy\nmetadata:\n  name: kopia-maintenance-nfs\nspec:\n  matchConstraints:\n    resourceRules:\n      - apiGroups:\n          - batch\n        apiVersions:\n          - v1\n        operations:\n          - CREATE\n          - UPDATE\n        resources:\n          - jobs\n  matchConditions:\n    - name: has-kopia-maint-job-name-prefix\n      expression: >\n        object.metadata.name.startsWith(\"kopia-maint-\")\n    - name: repository-volume-does-not-exist\n      expression: >\n        !has(object.spec.template.spec.volumes) ||\n        !object.spec.template.spec.volumes.exists(item, item.name == \"repository\")\n  failurePolicy: Fail\n  reinvocationPolicy: IfNeeded\n  mutations:\n    - patchType: JSONPatch\n      jsonPatch:\n        expression: >-\n          [\n            JSONPatch{\n              op: \"add\", path: \"/spec/template/spec/volumes/-\",\n              value: Object.spec.template.spec.volumes{\n                name: \"repository\",\n                nfs: Object.spec.template.spec.volumes.nfs{\n                  server: \"expanse.internal\",\n                  path: \"/mnt/tank/volsynckopia\"\n                }\n              }\n            },\n            JSONPatch{\n              op: \"add\", path: \"/spec/template/spec/containers/0/volumeMounts/-\",\n              value: Object.spec.template.spec.containers.volumeMounts{\n                name: \"repository\",\n                mountPath: \"/repository\"\n              }\n            }\n          ]\n"
  },
  {
    "path": "kubernetes/apps/overlays/cluster-00/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  # - ../../base/actions-runner-system\n  - ../../base/ai-system\n  - ../../base/crossplane-system\n  - ../../base/democratic-csi\n  - ../../base/development\n  - ../../base/external-secrets\n  - ../../base/game-servers\n  - ../../base/harbor\n  - ../../base/home-system\n  - ../../base/kguardian\n  - ../../base/kube-system\n  - ../../base/network-system\n  - ../../base/nginx-ingress\n  - ../../base/observability\n  - ../../base/preview-system\n  - ../../base/rook-ceph\n  - ../../base/security-system\n  - ../../base/volsync-system\n  # - ../../base/actions-runner-system/gha-runner-scale-set/ks.yaml\n  # - ../../base/actions-runner-system/gha-runner-scale-set-controller/ks.yaml\n  # - ../../base/ai-system/kagent/ks.yaml\n  # - ../../base/ai-system/kgateway/ks.yaml\n  # - ../../base/ai-system/kmcp/ks.yaml\n  - ../../base/ai-system/n8n/ks.yaml\n  - ../../base/ai-system/ollama/ks.yaml\n  - ../../base/ai-system/open-webui/ks.yaml\n  # - ../../base/crossplane-system/crossplane/ks.yaml\n  - ../../base/democratic-csi/democratic-csi/ks.yaml\n  # - ../../base/development/backstage/ks.yaml\n  - ../../base/development/open-feature-operator/ks.yaml\n  - ../../base/external-secrets/external-secrets/ks.yaml\n  - ../../base/external-secrets/onepassword/ks.yaml\n  - ../../base/flux-system/artifact-generator\n  - ../../base/flux-system/flux-instance/ks.yaml\n  - ../../base/flux-system/repositories\n  - ../../base/harbor/harbor/ks.yaml\n  - ../../base/game-servers/enemy-territory/ks.yaml\n  - ../../base/game-servers/minecraft/ks.yaml\n  # - ../../base/game-servers/minecraft-witherstorm/ks.yaml  # Disabled: corrupted EXT4 on TrueNAS iSCSI PVC; needs fsck or PVC recreate before re-enabling\n  - ../../base/game-servers/minecraft-bedrock/ks.yaml\n  - ../../base/game-servers/minecraft-bedrock-broadcaster/ks.yaml\n  # - ../../base/game-servers/minecraft-proxy/ks.yaml\n  - ../../base/game-servers/minecraft-rcon-web/ks.yaml\n  # - ../../base/game-servers/minecraft-router/ks.yaml\n  - ../../base/game-servers/minecraft-pixelmon/ks.yaml\n  - ../../base/game-servers/cmangos/ks.yaml\n  - ../../base/game-servers/cmangos-ptr/ks.yaml\n  - ../../base/game-servers/adminer/ks.yaml\n  - ../../base/game-servers/azerothcore/ks.yaml\n  - ../../base/game-servers/emberstone-portal/ks.yaml\n  - ../../base/home-system/autobrr/ks.yaml\n  - ../../base/home-system/bazarr/ks.yaml\n  # - ../../base/home-system/emqx/ks.yaml\n  - ../../base/home-system/home-assistant/ks.yaml\n  - ../../base/home-system/jellyseerr/ks.yaml\n  - ../../base/home-system/mosquitto/ks.yaml\n  - ../../base/home-system/prowlarr/ks.yaml\n  - ../../base/home-system/qbittorrent/ks.yaml\n  - ../../base/home-system/qui/ks.yaml\n  - ../../base/home-system/radarr/ks.yaml\n  - ../../base/home-system/recyclarr/ks.yaml\n  - ../../base/home-system/sabnzbd/ks.yaml\n  - ../../base/home-system/smtp-relay/ks.yaml\n  - ../../base/home-system/sonarr/ks.yaml\n  - ../../base/home-system/tautulli/ks.yaml\n  # - ../../base/home-system/zigbee2mqtt/ks.yaml\n  - ../../base/kguardian/kguardian/ks.yaml\n  - ../../base/kube-system/cilium/ks.yaml\n  - ../../base/kube-system/descheduler/ks.yaml\n  - ../../base/kube-system/keda/ks.yaml\n  - ../../base/kube-system/kubelet-csr-approver/ks.yaml\n  - ../../base/kube-system/metrics-server/ks.yaml\n  - ../../base/kube-system/reflector/ks.yaml\n  - ../../base/kube-system/snapshot-controller/ks.yaml\n  - ../../base/kube-system/spegel/ks.yaml\n  # - ../../base/kube-system/tetragon/ks.yaml  # Disabled: requires debugfs/tracefs on Talos\n  - ../../base/network-system/cert-manager/ks.yaml\n  - ../../base/network-system/cloudflare-tunnel/ks.yaml\n  - ../../base/network-system/dex/ks.yaml\n  - ../../base/network-system/dex-k8s-authenticator/ks.yaml\n  - ../../base/network-system/echo-server/ks.yaml\n  - ../../base/network-system/envoy-gateway/ks.yaml\n  - ../../base/network-system/external-dns/ks.yaml\n  - ../../base/network-system/external-dns-unifi/ks.yaml\n  # - ../../base/network-system/multus/ks.yaml\n  - ../../base/network-system/oauth2-proxy/ks.yaml\n  - ../../base/nginx-ingress/nginx-ingress/ks.yaml\n  - ../../base/preview-system/ks.yaml\n  - ../../base/observability/blackbox-exporter/ks.yaml\n  - ../../base/observability/grafana/ks.yaml\n  # - ../../base/observability/jaeger/ks.yaml\n  # - ../../base/observability/kiali/ks.yaml\n  - ../../base/observability/kromgo/ks.yaml\n  - ../../base/observability/kube-prometheus-stack/ks.yaml\n  # - ../../base/observability/loki/ks.yaml\n  # - ../../base/observability/otel/ks.yaml\n  - ../../base/observability/silence-operator/ks.yaml\n  - ../../base/observability/vpa/ks.yaml\n  - ../../base/rook-ceph/rook-ceph/ks.yaml\n  - ../../base/volsync-system/kopia/ks.yaml\n  - ../../base/volsync-system/volsync/ks.yaml\n  # - ../../base/security-system/kyverno/ks.yaml\n  # - ../../base/security-system/gatekeeper/ks.yaml\n"
  },
  {
    "path": "kubernetes/bootstrap/helmfile.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/helmfile\n\nhelmDefaults:\n  force: true\n  timeout: 600\n  wait: true\n  waitForJobs: true\n\nrepositories:\n  - name: kustomize-mutating-webhook\n    url: https://xunholy.github.io/fluxcd-kustomize-mutating-webhook\n\nreleases:\n  - name: flux-operator\n    namespace: flux-system\n    chart: oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator\n    version: 0.49.0\n    wait: true\n    values: ['{{ requiredEnv \"ROOT_DIR\" }}/kubernetes/clusters/{{ requiredEnv \"CLUSTER_ID\"}}/flux-system/flux-operator/app/values.yaml']\n\n  - name: flux-instance\n    namespace: flux-system\n    chart: oci://ghcr.io/controlplaneio-fluxcd/charts/flux-instance\n    version: 0.49.0\n    wait: true\n    values: ['{{ requiredEnv \"ROOT_DIR\" }}/kubernetes/clusters/{{ requiredEnv \"CLUSTER_ID\"}}/flux-system/flux-instance/app/values.yaml']\n    needs: ['flux-system/flux-operator']\n\n  - name: cert-manager\n    namespace: network-system\n    chart: oci://quay.io/jetstack/charts/cert-manager\n    version: v1.20.2\n    wait: true\n    values: ['{{ requiredEnv \"ROOT_DIR\" }}/kubernetes/apps/base/network-system/cert-manager/app/values.yaml']\n\n  - name: kustomize-mutating-webhook\n    namespace: flux-system\n    chart: kustomize-mutating-webhook/kustomize-mutating-webhook\n    version: 0.11.0\n    wait: false\n    values: ['{{ requiredEnv \"ROOT_DIR\" }}/kubernetes/clusters/{{ requiredEnv \"CLUSTER_ID\"}}/flux-system/kustomize-mutating-webhook/app/values.yaml']\n    needs: ['network-system/cert-manager']\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-instance/app/helmrelease.yaml",
    "content": "---\napiVersion: fluxcd.controlplane.io/v1\nkind: ResourceSet\nmetadata:\n  name: flux-instance\n  namespace: flux-system\nspec:\n  dependsOn:\n    - apiVersion: apiextensions.k8s.io/v1\n      kind: CustomResourceDefinition\n      name: helmreleases.helm.toolkit.fluxcd.io\n    - apiVersion: apiextensions.k8s.io/v1\n      kind: CustomResourceDefinition\n      name: ocirepositories.source.toolkit.fluxcd.io\n  resources:\n    - apiVersion: source.toolkit.fluxcd.io/v1\n      kind: OCIRepository\n      metadata:\n        name: flux-instance\n        namespace: flux-system\n      spec:\n        interval: 10m\n        url: oci://ghcr.io/controlplaneio-fluxcd/charts/flux-instance\n        ref:\n          # renovate: datasource=docker depName=ghcr.io/controlplaneio-fluxcd/charts/flux-instance\n          tag: 0.49.0\n        verify:\n          provider: cosign\n          matchOIDCIdentity:\n          - issuer: ^https://token\\.actions\\.githubusercontent\\.com$\n            subject: ^https://github\\.com/controlplaneio-fluxcd/charts/\\.github/workflows/release\\.yml@refs/tags/v\\d+\\.\\d+\\.\\d+$\n    - apiVersion: helm.toolkit.fluxcd.io/v2\n      kind: HelmRelease\n      metadata:\n        name: flux-instance\n        namespace: flux-system\n      spec:\n        interval: 15m\n        chartRef:\n          kind: OCIRepository\n          name: flux-instance\n        install:\n          timeout: 10m\n          replace: true\n          crds: CreateReplace\n          createNamespace: true\n          remediation:\n            retries: -1\n        maxHistory: 3\n        rollback:\n          cleanupOnFail: true\n          force: true\n          recreate: true\n        test:\n          enable: true\n        uninstall:\n          deletionPropagation: background\n          keepHistory: false\n        upgrade:\n          cleanupOnFail: true\n          crds: CreateReplace\n          remediation:\n            remediateLastFailure: true\n            retries: 3\n            strategy: rollback\n        driftDetection:\n          mode: enabled\n        dependsOn:\n          - name: flux-operator\n            namespace: flux-system\n        valuesFrom:\n          - kind: ConfigMap\n            name: flux-instance-values\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-instance/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: flux-system\n\nresources:\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: flux-instance-values\n    namespace: flux-system\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-instance/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/resources/spec/valuesFrom/name\n        kind: ResourceSet\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-instance/app/values.yaml",
    "content": "# Source: https://artifacthub.io/packages/helm/flux-instance/flux-instance\n---\ninstance:\n  distribution:\n    artifact: oci://ghcr.io/controlplaneio-fluxcd/flux-operator-manifests:v0.49.0\n  storage:\n    class: \"ceph-block\"\n    size: \"10Gi\"\n  components:\n    - source-controller\n    - kustomize-controller\n    - helm-controller\n    - notification-controller\n    - source-watcher\n  commonAnnotations:\n    fluxcd.controlplane.io/reconcile: \"enabled\"\n    fluxcd.controlplane.io/reconcileEvery: \"1h\"\n    fluxcd.controlplane.io/reconcileTimeout: \"3m\"\n  cluster:\n    size: medium\n    multitenant: false\n    networkPolicy: true\n    domain: \"cluster.local\"\n  commonMetadata:\n    labels:\n      app.kubernetes.io/name: flux\n  sync:\n    kind: OCIRepository\n    url: oci://ghcr.io/xunholy/manifests/k8s-gitops\n    ref: main\n    path: ./clusters/cluster-00\n  kustomize:\n    patches:\n      # Allow cluster-autoscaler to evict flux controllers if needed\n      - patch: |-\n          apiVersion: apps/v1\n          kind: Deployment\n          metadata:\n            name: all\n          spec:\n            template:\n              metadata:\n                annotations:\n                  cluster-autoscaler.kubernetes.io/safe-to-evict: \"true\"\n              spec:\n                containers:\n                  - name: manager\n                    imagePullPolicy: Always\n                    resources:\n                      limits:\n                        memory: 2Gi\n        target:\n          kind: Deployment\n      # Use tmpfs for kustomize-controller builds and disable remote bases\n      - patch: |-\n          - op: replace\n            path: /spec/template/spec/volumes/0\n            value:\n              name: temp\n              emptyDir:\n                medium: Memory\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --no-remote-bases=true\n        target:\n          kind: Deployment\n          name: kustomize-controller\n      # Enable Helm repositories caching\n      - patch: |-\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --helm-cache-max-size=10\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --helm-cache-ttl=60m\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --helm-cache-purge-interval=5m\n        target:\n          kind: Deployment\n          name: source-controller\n      # Flux near OOM detection for Helm\n      - patch: |-\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --feature-gates=OOMWatch=true,DefaultToRetryOnFailure=true,CancelHealthCheckOnNewRevision=true\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --oom-watch-memory-threshold=95\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --oom-watch-interval=500ms\n        target:\n          kind: Deployment\n          name: helm-controller\n      # Add postBuild substitution and SOPS decryption to flux-system Kustomization\n      - patch: |-\n          apiVersion: kustomize.toolkit.fluxcd.io/v1\n          kind: Kustomization\n          metadata:\n            name: flux-system\n            namespace: flux-system\n          spec:\n            decryption:\n              provider: sops\n            postBuild:\n              substitute: {}\n              substituteFrom:\n                - kind: ConfigMap\n                  name: cluster-config\n                - kind: Secret\n                  name: cluster-secrets\n        target:\n          kind: Kustomization\n          name: flux-system\n      # Controller-level SOPS decryption\n      - patch: |-\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --sops-age-secret=sops-age-secret\n        target:\n          kind: Deployment\n          name: kustomize-controller\n      # Watch configmaps and secrets attached to HelmReleases and Kustomizations\n      - patch: |-\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --watch-configs-label-selector=owner!=helm\n        target:\n          kind: Deployment\n          name: (helm-controller|kustomize-controller)\n      # Cancel health checks on new Kustomizations revisions\n      - patch: |-\n          - op: add\n            path: /spec/template/spec/containers/0/args/-\n            value: --feature-gates=CancelHealthCheckOnNewRevision=true\n        target:\n          kind: Deployment\n          name: kustomize-controller\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-instance/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: &app flux-instance\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  path: ./clusters/cluster-00/flux-system/flux-instance/app\n  prune: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: flux-system\n  timeout: 5m\n  wait: false\n  postBuild:\n    substituteFrom:\n      - kind: ConfigMap\n        name: cluster-config\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-operator/app/helmrelease.yaml",
    "content": "---\napiVersion: fluxcd.controlplane.io/v1\nkind: ResourceSet\nmetadata:\n  name: flux-operator\n  namespace: flux-system\nspec:\n  dependsOn:\n    - apiVersion: apiextensions.k8s.io/v1\n      kind: CustomResourceDefinition\n      name: helmreleases.helm.toolkit.fluxcd.io\n    - apiVersion: apiextensions.k8s.io/v1\n      kind: CustomResourceDefinition\n      name: ocirepositories.source.toolkit.fluxcd.io\n  resources:\n    - apiVersion: source.toolkit.fluxcd.io/v1\n      kind: OCIRepository\n      metadata:\n        name: flux-operator\n        namespace: flux-system\n      spec:\n        interval: 10m\n        url: oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator\n        ref:\n          # renovate: datasource=docker depName=ghcr.io/controlplaneio-fluxcd/charts/flux-operator\n          tag: 0.49.0\n        verify:\n          provider: cosign\n          matchOIDCIdentity:\n          - issuer: ^https://token\\.actions\\.githubusercontent\\.com$\n            subject: ^https://github\\.com/controlplaneio-fluxcd/charts/\\.github/workflows/release\\.yml@refs/tags/v\\d+\\.\\d+\\.\\d+$\n    - apiVersion: helm.toolkit.fluxcd.io/v2\n      kind: HelmRelease\n      metadata:\n        name: flux-operator\n        namespace: flux-system\n      spec:\n        interval: 30m\n        releaseName: flux-operator\n        serviceAccountName: flux-operator\n        chartRef:\n          kind: OCIRepository\n          name: flux-operator\n        install:\n          timeout: 10m\n          replace: true\n          crds: CreateReplace\n          createNamespace: true\n          remediation:\n            retries: -1\n        maxHistory: 3\n        rollback:\n          cleanupOnFail: true\n          force: true\n          recreate: true\n        test:\n          enable: true\n        uninstall:\n          deletionPropagation: background\n          keepHistory: false\n        upgrade:\n          cleanupOnFail: true\n          crds: CreateReplace\n          remediation:\n            remediateLastFailure: true\n            retries: 3\n            strategy: rollback\n        driftDetection:\n          mode: enabled\n        valuesFrom:\n          - kind: ConfigMap\n            name: flux-operator-values\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-operator/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - helmrelease.yaml\n\nconfigMapGenerator:\n  - name: flux-operator-values\n    namespace: flux-system\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-operator/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/resources/spec/valuesFrom/name\n        kind: ResourceSet\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-operator/app/values.yaml",
    "content": "---\nserviceMonitor:\n  create: true\nweb:\n  networkPolicy:\n    create: false\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/flux-operator/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: &app flux-operator\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  path: ./clusters/cluster-00/flux-system/flux-operator/app\n  prune: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n  targetNamespace: flux-system\n  timeout: 5m\n  wait: false\n  postBuild:\n    substituteFrom:\n      - kind: ConfigMap\n        name: cluster-config\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/kustomize-mutating-webhook/app/helmrelease.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/main/charts/other/app-template/schemas/helmrelease-helm-v2.schema.json\napiVersion: helm.toolkit.fluxcd.io/v2\nkind: HelmRelease\nmetadata:\n  name: &app kustomize-mutating-webhook\n  namespace: flux-system\nspec:\n  interval: 5m\n  chart:\n    spec:\n      version: 0.11.0\n      chart: kustomize-mutating-webhook\n      sourceRef:\n        kind: HelmRepository\n        name: fluxcd-kustomize-mutating-webhook\n        namespace: flux-system\n      interval: 5m\n  install:\n    timeout: 10m\n    replace: true\n    crds: CreateReplace\n    createNamespace: true\n    strategy:\n      name: RetryOnFailure\n      retryInterval: 5m\n  upgrade:\n    remediation:\n      remediateLastFailure: true\n      retries: 3\n      strategy: rollback\n    cleanupOnFail: true\n    crds: CreateReplace\n  test:\n    enable: true\n  rollback:\n    recreate: true\n    force: true\n    cleanupOnFail: true\n  uninstall:\n    keepHistory: false\n  driftDetection:\n    mode: enabled\n  maxHistory: 3\n  valuesFrom:\n    - kind: ConfigMap\n      name: kustomization-mutating-webhook-values\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/kustomize-mutating-webhook/app/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - ./helmrelease.yaml\n\nconfigMapGenerator:\n  - name: kustomization-mutating-webhook-values\n    namespace: flux-system\n    files:\n      - values.yaml=./values.yaml\n\nconfigurations:\n  - kustomizeconfig.yaml\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/kustomize-mutating-webhook/app/kustomizeconfig.yaml",
    "content": "---\nnameReference:\n  - kind: ConfigMap\n    version: v1\n    fieldSpecs:\n      - path: spec/valuesFrom/name\n        kind: HelmRelease\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/kustomize-mutating-webhook/app/values.yaml",
    "content": "---\nimage:\n  repository: ghcr.io/xunholy/kustomize-mutating-webhook\nreplicaCount: 1\ncertManager:\n  enabled: true\nconfigMaps:\n  - create: false\n    name: cluster-config\nsecrets:\n  - create: false\n    name: cluster-secrets\nenv:\n  LOG_LEVEL: debug\npodDisruptionBudget:\n  enabled: false\nsecurityContext:\n  allowPrivilegeEscalation: false\n  readOnlyRootFilesystem: true\n  capabilities:\n    drop:\n      - ALL\n  seccompProfile:\n    type: RuntimeDefault\nservice:\n  headless: false\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/flux-system/kustomize-mutating-webhook/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: &appname kustomize-mutating-webhook\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  interval: 30m\n  retryInterval: 1m\n  timeout: 3m\n  path: \"./clusters/cluster-00/flux-system/kustomize-mutating-webhook/app\"\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n    namespace: flux-system\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/ks.yaml",
    "content": "---\n# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json\napiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nmetadata:\n  name: cluster\n  namespace: flux-system\nspec:\n  decryption:\n    provider: sops\n  deletionPolicy: WaitForTermination\n  interval: 30m\n  timeout: 30m\n  path: ./apps/overlays/cluster-00\n  prune: true\n  wait: false\n  sourceRef:\n    kind: OCIRepository\n    name: flux-system\n  postBuild:\n    substitute: {}\n    substituteFrom:\n      - kind: ConfigMap\n        name: cluster-config\n      - kind: Secret\n        name: cluster-secrets\n  patches:\n    - # Set Kustomization defaults and HelmRelease defaults for all child Kustomizations\n      patch: |-\n        apiVersion: kustomize.toolkit.fluxcd.io/v1\n        kind: Kustomization\n        metadata:\n          name: _\n        spec:\n          decryption:\n            provider: sops\n          deletionPolicy: WaitForTermination\n          interval: 30m\n          retryInterval: 1m\n          timeout: 3m\n          prune: true\n          patches:\n            - patch: |-\n                apiVersion: helm.toolkit.fluxcd.io/v2\n                kind: HelmRelease\n                metadata:\n                  name: _\n                spec:\n                  install:\n                    timeout: 10m\n                    replace: true\n                    crds: CreateReplace\n                    createNamespace: true\n                  upgrade:\n                    remediation:\n                      remediateLastFailure: true\n                      retries: 3\n                      strategy: rollback\n                    cleanupOnFail: true\n                    crds: CreateReplace\n                  test:\n                    enable: true\n                  rollback:\n                    recreate: true\n                    force: true\n                    cleanupOnFail: true\n                  uninstall:\n                    keepHistory: false\n                  driftDetection:\n                    mode: enabled\n                  maxHistory: 3\n              target:\n                group: helm.toolkit.fluxcd.io\n                kind: HelmRelease\n                labelSelector: gitops.owncloud.ai/defaults!=disabled\n      target:\n        group: kustomize.toolkit.fluxcd.io\n        kind: Kustomization\n        labelSelector: gitops.owncloud.ai/defaults!=disabled\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/secrets/.sops.pub.asc",
    "content": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBGB2q3sBEADjCeB/XvSH5/AHpWAmwu9HcKH8VxXQYqBoGj9OrEjhzH9JL1jW\nJv1+17kDbzkFYi9f8p4hTExxUgjOERACz/nRA8f3r1LZ46yht5cKJLpqi3y0wvho\nADeP+IcZPex+75oqMJTTd28GeT7BVSoPkUKN6vsqtBmOL4l1BDLQh3dBiHpGgnMr\nRgId5hfgo8vjDHLBpFoCH5EjRV1i1YFwzRudwph2OVKVqCZADK9869LC1SG+TM9V\nQ4U/eGkNw2H/JW4FAdtroYseu5jJ7zFZbvaGU8Mc0IrLhwBGuE5BRuvk2xzvZCQn\nlbeLulsr5n6+u2RJSrk8BHhZsZUrdmpbfeQNmACddkmBGxv9+HuZF5dC11iYrs5s\n3FF2tqhEi/OTyafI2cho5ICd4lnXMD5vOofaik2amn93TPhfkK0utaMwOJUdfusf\ntJn91T6J5azNnggaMAiSOy9cTIDc2CcW4FbUyNk6mBmoKVfHL3q+ZSrdubAfCnWl\n0JbyTPcRKE/ZQcOd5OpmsjSRU/Ih8TmRYFcC2XzYsgRgIHCFANwu8SbALEe8VsSx\nImt2sdCIPLr9VIHW8ZzYc/rOHcllXMJDhIER4GUZWwKxahURPeSr8gM1qsCrvnSx\nISbDXwnep9hBtz4IjADEtdYcDxXTwik6NO0xDkDs8RH+Cz2Gu+8DP4c4aQARAQAB\ntCpwcm9kdWN0aW9uLnJhc3BiZXJuZXRlcy5jb20gKGZsdXggc2VjcmV0cymJAk4E\nEwEIADgWIQQGNbjTQDepRTAD+3uTyqaC/0yQFAUCYHarewIbLwULCQgHAgYVCgkI\nCwIEFgIDAQIeAQIXgAAKCRCTyqaC/0yQFLuREADbBdBc3YoFkt4bKElFPdhKdIQE\n421Ocw0Eehk+/77i1/M8VWdG6yK5QM5eZerPFDT8Ma7b51Iz+jDiBATV3cZO39ls\nPXrfiFg9AB7KBB69/psK4DekmZQUBGJzxUzkzZFkv4LvOVt8W0ekVQ2KV/WXpSH9\nk8pqJYGmeui4cpoLzBAOpbES3XhAWz0yQJ2LhT5pAQZItDRK2EhXsDEL5LFWq8tV\nKxEsiq01wQgjFiguGhi5yCjCkgy2Zkk3stFQOrHaEaUOaKtxanLdZ+0SxMOFVfpH\nUI+kJYsTbNz/QvAG1ypfuHljEjDLs5RaVBpeDraAxmYVTwDDyYZqhiTLtEBfb8ED\nbYcb7MFSWyCJrF0UtRocf5XV0QG/tPDB2EfeXOGgpRCAoWmNVVZkTkYJDT8Izq6U\nJkpOzNzoMrwgZ9vt3eKEffTANcV4EFHZcCw37xlWecb6Un93y8CXYLF3M4ia/9mo\nCGCs6nQdUjaGeslViYarHdgUD8XxJcCanX2iGMzK7m6bUe+CENdi/fik1m20HxjD\nxjCESqINydzGwkEt/YQ2jBpcNe0DLsRHbadI20IGcA/ZFhzZtPGBbKU556gVxSoE\n/dq4w/sW+2RMhXtO2gdbN+DIPTelnzyaEA2bsLQA7Wj9GVBK2UnTwMizigsueLb7\nQL+lq+9yYwGpdP5PN7kCDQRgdqt7ARAA6g3jlUqyGPqNGv5mSKGbOWGHq70oQmdt\nL26bzpKk1fvpQIlJnHdz2pSgjAHquTgwkD4fgeJ+fW4qlfXk6b78gSdhhWySx6CD\ntW0AAtGwlgeBVvSmNPyLdqdMrfJw9VwYH/pY520q5e5Pb7ekf5U9GJPioXe37LME\nHx6t2NCOonRHhtN4P1GfigJ+u12o+bh495NtQ8LXULaFQJlbQ6W+jkSDkA9mBRzi\nVN+loirnXw1jtneMpQofEGLdyg6NTXKQjb76GAVMUmp69d1QfCNEobGXvpfurpye\nEiC6IPiXh/sKMcei/sgkQhjELeB0rQH6maxVFYhmZjuXyEZe8dCwSCRkRk45fKrC\n0ssGC1F434IWBOMMgfBdOzlPr12YWX2K66+53cRUteNpjiPh47exJwJ7Y2aNB9ZH\ngWzZJTzHKWFvFJs/uOw49i4BiWfWNtTxx7s2KrszRgptkFsDwwJPD5y6FCEm09kQ\nnma4YpYF/ELYSbEYMaZ9AytorUcmAR8X/NGjcgFE1HfhUTHjJGI188BT9/1Y/U5x\nb4SaMuU34KlcCqCrMhT5mP8BvMfxVupnLwJljNt2y5xuKF7Cz3jnzfOtvAz9kjis\n1CRlC2uidlR2uP2ZeMGi/u0kYl2+T+aCEO2VT0QPzJy/PIyOZTe0AH27rrIu0GBi\n9iDdO/OUe/8AEQEAAYkEbAQYAQgAIBYhBAY1uNNAN6lFMAP7e5PKpoL/TJAUBQJg\ndqt7AhsuAkAJEJPKpoL/TJAUwXQgBBkBCAAdFiEEVoxsIKvW/lYIGyuDHjaWYsfC\nhnAFAmB2q3sACgkQHjaWYsfChnD8xA//VY1dGBo4ThP7UdqqurAK1yHAJrjmmgk3\nvyv9pnte+ESBK+S5Edxv3g1wH9HzEQC32ybEH1mAQ1YFzIrpJavs8NZlK00hnF8g\noo1itJb6gBd6rVHyLjHtiIwCxSWVy2ZuIOgb+Pv9/XCJkW/hh6zH6H0DS4/aHuZu\nXLifhV8Yg89Sz/cG2qTLc/aFuWsagrFg1GtgiKt/FcubMyL/H74vcwO6wdDNbGh8\nIrP4pk+0O5GDe3AXAyOfQtN++GXwziFSpG0ggOyXB+Vhy6wgwvqno/0MESp1v1Qz\nvJyya0Op5PP9R9LOGrU1xjPAug6HVMDqSz68etptTBYAcWjVWrWtkIPYvcg7uQVK\ng5+aXvy8UbTJ1jNd6ccpxdjQiKTtLjxT4UUcc2n5j1Tr7SzLFZhiK/N/DGxiyjVD\ncenoJ5zzy6OkQ85izy7jnAqQM006F+4CyagWZInWDDEme9e6oP0aYLIMYY8QwCG6\nE/TA7vQvRFL2iY3jygrqwlLOTSufJL0W4NaYuUdrxdCf/JpkxptLamtcxvWmbSBO\nkHVnSY3hDh6nDYoVeUWdkx4z4wnCf9YtwpzKtmIY0hVkvXqyNUi8LqXZK3BzgcEF\negQ+gtIC5lpChrf/rc1ND4E9K8HRujPopVSPWb+5Zzjy9LRPt2NGNJwHcS05l6Y+\niIfy7hJt8q1rpBAAshPuXX+8Pby+WcB5oZ8oNzAwlho2JssbXx91jQFxFBt/tRF2\neKVde7BbFPtuyKYjZ2MQ05j6ieiQ1Hs4Q41dBfFwxBt8jg99JfYTDO7+wkIQSqmz\nFFv5reoxuR+viFuI964VALHuKDzHI+eICaoxw8qdO/X/0pRaU3pKOcHjkIYpqVHU\n8IsItyX+gmajbl8egK8KNmxPmekWMQs8uzNGgdPhCwmrJcfZ5mhH6bAoWUsd8GLc\nEb5ZPhyBIuMiPzdiTzpmQAAILlNnAFrq/rZDbekth7TAP9Jifz7dCXlHtTas0Q1x\nNADyOB3eODniumHqS54paZnxIqB6cwgZHYui7d6xToCLFjT946AiMmCGFxFDQ3SX\n5Aay7ybySQeNKf3X8fJaz3MOJ86SSjJ9A1kHKcZVxQslQc+atyUPt2K2b+fadedK\nmCVKe2Zz1PUsu94rjtA3ORR584UUtjsjwTEeIJuiIad8ZbEe/lqgChgh6pIq1uTZ\nzPVSmRk0dxiKX2vGdNyzDuUceAUXgHQIieluQttlFNS4cMzqtq25FQwFtbAKfx5g\nkK7Sw7vBagYUnzxHoOcD/HU76jM2S+CmTM+d6AQWWnWIrBzZ8ryu0BweU7MBMKJF\nhPLwoaJGpb+COl/c1CqXopLrvnVVPN2KjX68kLlXmSWeHIdBqYIsE8D2uYo=\n=gfGE\n-----END PGP PUBLIC KEY BLOCK-----\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/secrets/cluster-config.yaml",
    "content": "---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  namespace: flux-system\n  name: cluster-config\ndata:\n  CLUSTER_TIMEZONE: 'Australia/Melbourne'\n  CLUSTER_NFS_SERVER: 'expanse.internal'\n  CLUSTER_NFS_PATH: '/mnt/tank/media'\n  CLUSTER_ID: 'cluster-00'\n  CLUSTER_CONTROLPLANE_VIP: '192.168.50.200'\n  CLUSTER_SUB_DOMAIN: 'prod'\n  CLUSTER_DOMAIN: 'owncloud.ai'\n  BEDROCK_BROADCASTER_DOMAIN: 'bedrockbroadcaster.com'\n  CLUSTER_LB_MINECRAFT: '192.168.50.182'\n  CLUSTER_LB_MINECRAFT_RCON: '192.168.50.183'\n  CLUSTER_LB_MINECRAFT_ROUTER: '192.168.50.184'\n  CLUSTER_LB_NGINX_INGRESS_GATEWAY: '192.168.50.185'\n  CLUSTER_LB_K8S_GATEWAY: '192.168.50.188'\n  CLUSTER_LB_OVERSEERR: '192.168.50.190'\n  CLUSTER_LB_BLOCKY: '192.168.50.191'\n  CLUSTER_LB_EMQX: '192.168.50.193'\n  CLUSTER_LB_QB: '192.168.50.194'\n  CLUSTER_LB_MOSQUITTO: '192.168.50.195'\n  CLUSTER_LB_OPENCLAW: '192.168.50.192'\n  CLUSTER_LB_INT_GATEWAY_API: '192.168.50.180'\n  CLUSTER_LB_EXT_GATEWAY_API: '192.168.50.199'\n  CLUSTER_LB_ENVOY_INT_GATEWAY_API: '192.168.50.181'\n  CLUSTER_LB_ENVOY_EXT_GATEWAY_API: '192.168.50.186'\n  CLUSTER_LB_ADDRESSES: '192.168.50.180-192.168.50.199'\n  EXT_ZIGBEE_CONTROLLER_IP: '192.168.50.165'\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/secrets/cluster-secrets.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  namespace: flux-system\n  name: cluster-secrets\nstringData:\n  EXTERNAL_IP: ENC[AES256_GCM,data:HG/QAJtomSpBFBgl,iv:9J2Plep3mf7B9Qw6cBidunPbGiFd/83o2GF+30nQExA=,tag:ZDaCgh3T81DJGvvhQsWHVA==,type:str]\n  DEX_GITHUB_CLIENT_ID: ENC[AES256_GCM,data:ZbbvY2uuh8cHlRQatFU43wDww3w=,iv:OjwI4tY31Qf72n0PfbwU51L6wbdud5LhMyyZCU5GgJA=,tag:vnmC7xcUmjfY4yqZf4tYSA==,type:str]\n  DEX_GITHUB_CLIENT_SECRET: ENC[AES256_GCM,data:AIFhn7UhAG7mpYCDrB10TxtrvQ/Q0uAvXWxJxgMPLzbatoN+v3v9jQ==,iv:Xby2l4gA1D3RnpBZ+AN80jF73/wLyW04eYq23upYKRs=,tag:LHb9hKfAUWGkOgJRzgUErw==,type:str]\n  DEX_K8S_CLIENT_ID: ENC[AES256_GCM,data:1s9+cvHqE3fXYYSq8aTg/aP39IgZ,iv:f4DuTvRMunvWOrVqb/Tky7OlAMou96uiEsJXt7uhzPk=,tag:N47Z3z17ye5+xD5b5YRf7A==,type:str]\n  DEX_K8S_CLIENT_SECRET: ENC[AES256_GCM,data:0TmnfXaY6zWJPLqK4LhqjCD2AFYSRk84IyZTc0k5oZEpqRKdZPpq5d46,iv:wNFqZHcyH1lv8sNRA3PkYV/SuKx4V3vYyQh2XI7GdQA=,tag:rRQ2GanOCbHBJdlo1rUP+w==,type:str]\n  DEX_OAUTH2_PROXY_SECRET: ENC[AES256_GCM,data:PtnObm3LndrHmUTFTWZmC2uTTJ0=,iv:NDZAi8vsjAJWcntVl16qDRBjCuM0h8MiRbe2yEvn7+8=,tag:HMeyQI7TMW+XcxtgiIRp8g==,type:str]\n  DEX_GRAFANA_SECRET: ENC[AES256_GCM,data:L3rnANC2Z2lXsDrRuIQnIv+KxwB0qORE5kHlvEXhltiPVA==,iv:eHy1xFT2d0p/VmbB7ouYLqtXs5jBJ0t+F5QQmvv+u+c=,tag:rsNkS7BqeaCBn78AhYfrhw==,type:str]\n  DEX_LITMUS_SECRET: ENC[AES256_GCM,data:bNs/U+DFkTUCDrA7u3IuuYjQoTzg1NNT,iv:LSRKKN7yBwFEzwKvXdpDHRnZPFSVDolCSL5vjpKLYd0=,tag:faoHbPnM9ER/U2C813mDAA==,type:str]\n  DEX_WEAVE_GITOPS_SECRET: ENC[AES256_GCM,data:bjvKXMgvAGEsh10cdmcEtg==,iv:vUClQrCpSGNpbkLIfwwb2Kb2pnp8PfapEnV7fdvm1gA=,tag:rUpCabNvs/bfUPEiAfKtSw==,type:str]\n  GRAFANA_AUTH_GITHUB_CLIENT_ID: ENC[AES256_GCM,data:vL/WwwTAOr/emKUJWygyb0BTVqk=,iv:I/wk53eeZ7Z5weqYK4y05quysT2lskncnl17jf4OuyY=,tag:NRqNPDgQKX+/6rU9QnsMmg==,type:str]\n  GRAFANA_AUTH_GITHUB_CLIENT_SECRET: ENC[AES256_GCM,data:jdObYxhiyb+5zkTKFpP8FNZai4DWzfrGZRAkwt0tbqO/tsHesTxbRQ==,iv:MmYuNaIGvphHWGTp4wlsglYYUMaYQH3jkBpIziF63/k=,tag:AqP/PHNBkljUhreO/dTXSg==,type:str]\n  GRAFANA_AUTH_GENERIC_CLIENT_ID: ENC[AES256_GCM,data:o92TjeErDQ==,iv:48qO4F0rIA6E8uTTD7F1jq8unV94xvTMQLWb9/K5aG4=,tag:bC/UtDY5JpbO8mvXbZ0Osw==,type:str]\n  GRAFANA_AUTH_GENERIC_CLIENT_SECRET: ENC[AES256_GCM,data:VbndWckrnU+Jhhff33ZI/zk+k/lg40auswy4gZwIYIF3kQ==,iv:cTySCO3qLFrJ1sRyRAhMvVgEwya1JkZzPmJEGGk4j9Q=,tag:1Ms/jesK5Zxo9UC8EB8z/g==,type:str]\n  GRAFANA_ADMIN_USER: ENC[AES256_GCM,data:4N9/low=,iv:0K1v5t9XWAfiUV5hDby0tDXVjY2nFYlF5Tk959W6Flk=,tag:ewhHe/GAkz8bglvOUsdFOw==,type:str]\n  GRAFANA_ADMIN_PASSWORD: ENC[AES256_GCM,data:SH/QO/rncxk=,iv:4yKOLMrPGYIXYT5mCHW2WeCrnavTcP+WGXBAzQ/3qqE=,tag:w6jW9241XriqB9nNLs5TRg==,type:str]\n  THANOS_GCP_SERVICE_ACCOUNT: \"\"\n  GITHUB_ACTION_APP_ID: \"\"\n  GITHUB_ACTION_APP_INSTALL_ID: \"\"\n  GITHUB_ACTION_APP_PRIVATE_KEY: \"\"\n  CLOUDFLARE_ORIGIN_CA_KEY: \"\"\n  CLOUDFLARED_TUNNEL_ID: ENC[AES256_GCM,data:xEa9Ms0uo9dIaDBeIfnbsmrEyv8qIGBwhlUM923j+nRegV98,iv:dXosfnK9XGmTRqdza/Y6S1kJ53HM2hyYcguTAbAu/bI=,tag:LUJ6PWzzVDJ1F8my3TDtYg==,type:str]\n  PRIVATE_EMAIL: ENC[AES256_GCM,data:vWZ8vTJhq5hnaJlV/hEhVKpuCjkj5j5S,iv:cHrdn9Ft2B0vKSSpXKsH8uT0ufmayCxRWPl2UmPJk6w=,tag:yq0vSjAj/N/f/CRTOcbDsA==,type:str]\n  GITHUB_TOKEN: ENC[AES256_GCM,data:RAusWFjYjs9C6tgALZSVscLkDHSIWZ/1FzA6ogO2Vi7UTTAljWR3oQ==,iv:L7phiQyBpKlcOvigVzN+3MqPbbJaJFCr46pmuOP3sH0=,tag:veamaYUJ31eI8tW4iwc1Kg==,type:str]\n  MQTT_USER_USERNAME: ENC[AES256_GCM,data:dWrMrw==,iv:1dkVW79CQIPjmFFTNtBvOVjM+s6rrd6Sphi6w0ikxPQ=,tag:Ebet7FrWm27K1NKEEyFkeg==,type:str]\n  MQTT_USER_PASSWORD: ENC[AES256_GCM,data:T9nKPj5Mld/EeE7aP3JNo0ocPiqrpnNPGO4vf/ZqJ/87WA==,iv:dS+PAjxrO9ugcHJRV56PxZh9uKLpjrZPebCKQcVxZzI=,tag:vuTirKSN75BrCLRNeu9p8Q==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyeXF3dkZUVElyeVBoalBD\n        WVdYM2lnc29GeFFicElROTZiU0xiSk9RQVI0Ck92YnM1dnpKaDJYTE1vRFF6emhG\n        MmNlbkF4UXpZYmVoSVNwR1FoaDFVUWsKLS0tIGtCaFZFZVZOakZ0S0ljMUpmV3E4\n        VXdDME5ISHdDdUY0RFZYK1RtME4rcG8KTLrTE62ZhPq4AqGltINuoXOsWA+59xcs\n        hDANcOVkzyizx9+J86cUnyhqMdTufkTeReDIkZgY9eI2JjZqkl/XIQ==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2026-03-01T01:50:31Z\"\n  mac: ENC[AES256_GCM,data:mwDEpffJ3iHgjry6RZAkftSVGodTvkIadDvL/sIZ/ohasTE46LsygorWpkHaxN0cdd1+4v4PDmmdUiZcN2K5fCz2WZP7R3aRIYJTS2fh9Fqd9UHNwqgew1f5F3eVTD6+Ba7mqwbr85wby9Qejtf2iry35dbyFFTiQ+V54Q6FFP0=,iv:DNErVskSsU+/6HAvpGwJD3NZb024pmU7DhgSfD4QMHE=,tag:IRb0kL/DnnyjPtD8A6kLIg==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.12.1\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/secrets/github-auth.enc.age.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  name: github-auth\n  namespace: flux-system\nstringData:\n  githubAppID: ENC[AES256_GCM,data:0vC2xlO4,iv:JhiQFonDvYORyyqyFxF1C37cffjg6TLibf5fXIMMtjk=,tag:mZDLaAdjnNv7JK6hMN5D2w==,type:str]\n  githubAppInstallationID: ENC[AES256_GCM,data:ciZuppuaRoA=,iv:/blv2vqprD+eHK6220FkuL+6gMU4IFK6/9q97ZzTKUY=,tag:iFeMLsZoirPT/mPUlLvkrw==,type:str]\n  githubAppPrivateKey: ENC[AES256_GCM,data:W8DwpspaW6jlwsah/4iMZdJ0d3mT9Yl814nZToYSuBna/ZYlGZstP3FqefpR+JfKukL9ytqfQyP5ZlyYaBiDTqlAqF/4OFwGPSt0Qn9ywCIAmwhKqMPvNVhdr12rJ/DkFnuDi4qfS3aV7k28oaX8ZbWLGlv6jp3qf+gm1LsLxDBaOofnaha3LZbhOP14HUuuxi/4Z4eiz6nncnBeXfl1mvdiuDqZDtxwNe+Fwy+ZAUZirDqm26qvCnuXkfFPbHd3Q+Jn/sA29Qblg901izMuDK+B7I17L3cDgx2Yymvm2bfXUsmtnQIPfigmA2zLQH2dT8/FV/Z/72UxYJWKBsljGA/QzMZQK8raFmcCITzFMG9YxqLeeyv1bI8EBV7iSsW30G8LyDn0s2+x/v7eM9kVhEEJlfhYYPfRDEwcMoPXYgo6oHzOraDBu3Hh2SJuEyApnTRXOJ/N83QfVMZ0BqRTQblUtl8W0InZNl7t2wDbQxPhN7rnsVTbiQgEXSGdYv2I0S0xWQH+Qzv5bRV0+4zuyQz9SJSWzYJ2pUAl6d3FW1swI1dpU+f4SI1cTSRRt/PGIoGEf6SGKbT0TKGAZYSKuSrDRfiplLkVIRc/P/Dp0xL5cFekIZStONmKjl7CzrddlL51+H4wYmzukjFGq8FwTNNIdrySU1HqkVRle3KgupnWuKE6rHiq3mFvGdZNOA6BVamb+lnWE2G0Xa9g9mGXxqBBKsnM0TFP01k7+QgOggAl5dnDN63RKamoNMYD/WQdVMQUFUukQ9iwM7Clyx4l411VoiRI8NqPi+4dh6ALlxVtnWIuacUkPXTXwbDoceSQetWafs0V12ocI20S3RzCezqGAXvmyzYPW+KLiYca/r0aU2XZwwhudSrpDRqgsHkY6nEj5VqoxSevdLSOb5HJYZTcNKlyae2nAVK+3ttD8DZvSWJD7eqrr8v0G6BUB/Mbz/sjkvl3Mb1Ro1a0u8YgugkjWv/tCiLVGGx3a25tKOoqtAEDce+wOjYWt6KF69/7VCGMuCuuxBdLkLZEgbZ8nsV7Pu99Hx9YnuZpSRwzaOZZ2QIv/YfqMmLWVaWazTrdAlWX6bYld4RdaCdhN29v2e2S7sDdI8lHfEvqP3JVA7oUT+SLarIQePSHgY0nu2gtz8jGS+BB3YWTW0TAm5pdh8rbbmHtD9C3VVax5/QBs5+3c86IGy0aDfRoCWhYtanNJP8lpiwujmhTikHH/QTIqDt3U4yJ5S/391ayApPCoMemhraQ45CqQiFa3BV9Ul4As2z2cpIdejtlMlVDIpanGdqDwZxc+f3bJZ3y+YxluTJD0q0cr+qF24pfHYybmuJ9ygnvNBzdh5e39YVVuFO3Z+B92FGqeSbTBX9S+QYi3ldDJB8+IailVPqgOe5YYF7WrvR45dVNktQgOec0x2W2RpMQqO/iJJZbVyxu1+y1RI7zfqICogYvP3iID5G+vSTBaeEoIQQbjCReGHgNxfjLBg2TsigxGR8OtTwZb2UdcGHY9Dqln1olywIwZqAzFLxGUqg+4FD/DAWL1bhFxXBhO9h+wx/xRJg5GUCaF3mO4juipySCSLdPM+pdUT4QYSlP5Os9frtDvyXUmo9tEP5IPQDtqjaMixp/0x83oqzsX5QmnfTySAw3QeTO3earJ0a/TU5W+sC3ftLpV4Hi8Ns/sAraUbtFTqbewxuBMEdLy8XOIqmiGKrtdfSsrRo/YDr+7xsKZp7Ow0iT75wO+oroqhekZa12B7lOwep8UpYl5KY5sOPWrsGlpuY9rVwS16JsSfQLHXrOrs6jenrkVYzFHVVq8avhpHQ7ShK4D2n0Py+a2FZfWSNEf+M3A52Kb8+xzQv46y3S70BmYIkH1nTKR5MPKWSkYC3dreX5mELKDVm3MpMepOjN85ellDHstYMCbEaydDFfJdS2bVb6MHEEaZzaJ9Hw7nwxMKXnRxq91cjCYdJ5SEfUKnGFz3K5LNnptYmVSsnA8/6VUxSP29/e42USGIlTARKdedK9ySY6dwmTyzJPLHZBA23lhk0GX7QyjEuywJ49aLwVKw5sWoXvJaF5niSPAPsqw4duhhSlktS8NEQbIH8uwSCsX10Tjs1LD/eMMVdAbhKrtI0sfLfutYUiRVPsRyxKgNsZrPeRhDpxGMMs7IQv9zyLBsXVwTxrmA3H+ca8d0ZlP3kIGBzWhFqISdG2Md+UFCQfeZ295y2AIBjV+eMyEb++Zg==,iv:CTYMlYy5MtdSVXAkp+NaHPxrB0qE3ZOhBkDD6L3dpyE=,tag:mtzQFpxWqSGY4/UfLRn96w==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKYnZkZEpXV3ovK3dyL1lV\n        b0pJOHJSdjVldFRZS3Bnc1E0S1FyYy9ONlUwCnREa1UxU0xWRFIrMjd3NkdYanRw\n        aVRYc3c4b2dZUHpuMkxvRWV0andZTGsKLS0tICtGQ0JBYktyMWtRNnlaeXZzNUhF\n        NllMam53MVFyV2dRbHBrendPOFNFZncKM729SpIHkpSMSP4UjlbzOB1Xf7UxCFXT\n        gv74AjVrTcqxXNpUT9f42rvf2uRq1dum6sk1azbyKAuLYPFSKXM7oA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:41:08Z\"\n  mac: ENC[AES256_GCM,data:oMGwTbAUcLbQgNzIu6zlPiJLg8VkR8SNDshQOQAEtNktOsQK32fikUToskRd8rfOSbrtscCew0llPn+6GxTlA1+8qVp1Vy/2DbdLG+0tksfIqSgE6MQCKjDMx74zDPIn7ZPEtU6ZA2YsoC8SWVUMShfQzAeO+Yv6RJypqvVPXuk=,iv:xTojCvCTymvto0H+PDvMROIoqkT5XfKz5GjF7JFAJi8=,tag:rHkjR8vZ0FXVjC0HLjJuQg==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  name: onepassword-connect-token\n  namespace: external-secrets\ntype: Opaque\nstringData:\n  token: ENC[AES256_GCM,data:s3beJIu5Qq52Ud4KKZdY6G6Z457LIbCYMU8MgwQbTJvHh3BzFDQIWpTAHjU3uE24L2UG0I6bUHBKPj6LDYi3l6+EHQ7WPDK/Nm4bqzaCQE0SB5sf1l0TndT4/ZlFIq7lo7dyhXy7QY4I2xahckKdnjTqG728pjcPhOvC1jUzHGePYNTkYL5hU4nXSBtv7qLUIKEFrJTKBR3DBpz7S4JehSXSx/AWBOPMt6ZeejvzuusbVvF/c2jglWyyTs/nPgnocJg6ujnB7+jqr07RZrWufPXVQHyFpdkpoNFaFHSQ3r3AK8AdVKvBU/hLd/MxVj3HvLlNY/9dBF7IhpjtXkER14txlsLvtPONmf8YTPVoCOLHKjzvbM0ClQW6nKVPAVllXlYe4xNQJe8y2K7GMp+pQpLPEINkD/OIHVRJdNer9HvO3k0CfJCKMdxaeHxCxPp6xseQA59Qmrcy2imhojDoHh7MtlGJAb+5VHp55PvQo87HUlczDYj3CiYXngbxbWMNHIZydUnpDNLzb974vPHPN69lMOVoBYRQhZZF7EkqTOuiE+LHeljePW8p1GSfKwWRqEsEj8VbnghC2vqgbMtiHpTiZMM6naBzdvSoouxmGiGWKFscQSUl3uYAtd7BsoDFShUyR0HzEDcmAnXVhXInuUo1UC9yRFBCy7h3vYtGY2BsMYmgSTe1jN4J2/yhDvN7qn9aidupb9jCk3ZR1FjnBC0xhwGEeDVC1QHmHHpog90FzW4PwM/3GauJxI1H2Suh1VXwnnmPQQL/VV2NEsXr3mXbyjdtMg4RTlH73beH0w/zorcyvVBaVJAeykQ/s6Uaz00upbQotWy8YaILu4+sYO9+,iv:NXZqFg/sXGTbxbJNW27g6BURSz/uF1a1OcsGlT0r1GA=,tag:YBKb8vUSt6ZotLqEPFL3hw==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKYnZkZEpXV3ovK3dyL1lV\n        b0pJOHJSdjVldFRZS3Bnc1E0S1FyYy9ONlUwCnREa1UxU0xWRFIrMjd3NkdYanRw\n        aVRYc3c4b2dZUHpuMkxvRWV0andZTGsKLS0tICtGQ0JBYktyMWtRNnlaeXZzNUhF\n        NllMam53MVFyV2dRbHBrendPOFNFZncKM729SpIHkpSMSP4UjlbzOB1Xf7UxCFXT\n        gv74AjVrTcqxXNpUT9f42rvf2uRq1dum6sk1azbyKAuLYPFSKXM7oA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:41:08Z\"\n  mac: ENC[AES256_GCM,data:oMGwTbAUcLbQgNzIu6zlPiJLg8VkR8SNDshQOQAEtNktOsQK32fikUToskRd8rfOSbrtscCew0llPn+6GxTlA1+8qVp1Vy/2DbdLG+0tksfIqSgE6MQCKjDMx74zDPIn7ZPEtU6ZA2YsoC8SWVUMShfQzAeO+Yv6RJypqvVPXuk=,iv:xTojCvCTymvto0H+PDvMROIoqkT5XfKz5GjF7JFAJi8=,tag:rHkjR8vZ0FXVjC0HLjJuQg==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  name: connect-server-credentials\n  namespace: external-secrets\ntype: Opaque\nstringData:\n  #ENC[AES256_GCM,data:2mdL0YubS+p1SGaxwaiSJOQIJWmfoCdJe62RgcYzntRh+zFWjHELRr3qCS06t2N/gGM5qF/KSRA2ZQLA7n1GpkSY6sb6bHUkY3spTZ/RpBe407T+ITGAGOUyNk5uugjbLUI9hGeK7/E2dbhTq7tmA8RRWcCbqjoG4Vi941dGYLIL3gHS6+H2YaUJMxe9xaA5tLPtGFmaSC8WcUnGsXNiv9t6O9VzOGpW36iKt3KtLZQT4nI2QkxWHvn+4A==,iv:rzfcfhcWUDOfUJWTGVzKNT00bx/mIAerp3M5aTIZWfU=,tag:ALn/+ZtlkELPzOsLxTJgQA==,type:comment]\n  1password-credentials.json: ENC[AES256_GCM,data:X4INLMMsjT5JJ52TkD2G0Ph18ju++3f6Unnl+LRdwQGpb+62UaRCM7uaoZEILlEu3P8Bc0CaqoISVi98pfQ2PQBjtj/DHS8fYz8sg039QYdfX7CDvBfKwqhFOsO2XoDTumaKxwUgJxK65NyNrQjDGc48928taiUHDxhgxt/F9cUbIxx0EkWJfN8HObbQwqsAmJsmjhGOuInpjXIghIUEo6Mv50P29MJqvsNLjgDCXw+EDeI/oO94+/Dv0Hhz1tjX9GhGdEkJtNHWn6I6PJaQYdozoKubfDtPni9HoJmeQHu7zykJABm2pQbTeY34OHkya2dbEO+LyV2E+wTxiZxwAI1zOacU2vkaLsFBM1IEAH9RJEqJ5VxZdnOokHujmzOxBjB5Ez0nfM5E5qX9kK8cmPWtSSwOsK6B5vRv7wqt6OrFweiDBFrdoaQblfbJLyQ4KJtfw/LZHsoZyxmKPlVnHqv1PvOImcKyoz2OnFf6hBKNKs3wULmeVc3Ir7kbPfrQdE74KCCusFEopwqSUzQJtuoBXPJQqKk4yxvl3NxEx3gwX/W72j4WXwEU1EFAIIDaN+ZoV2hg7Qfuf29keIMOHAesEpnC41zT1mB8FtQSSPTCCnQIQWDppUvg8K0O9kS85fpwZfJZV0ZUVEiNRWauLu8xWO6HyrXv1NE2r1spBj5IV5to2jS3h2HNjZccWL1JKE6S81XxILWFsj75p1dbSq7s/KKqSXw1yqs0TBgz0YJud8kAVcqtX+qcSj1n8L8wHS3PmPVXzDNFPqY7JsZc/5L2/CSm5QJrIdJ2sFIKB3QrcpB5/7odqwCz6dVkQ00gHO/BzLXRod9akb1TEqm6jsKJR00Lg9lpMQKN7+e7g9R4qfzN2DabQTlFoZNMLxTABJUAVFFNQjSvCtXpvXl5g+vruR0wivY4XMMo2s1t7k42b0QHk4IocsfsGHl8ifpf8eAsELHyWwEVKqwX3e4daqfyNE4Hc3oDKlryaugIrqpCeDcsIBqr0ejgTPdYtaX5Pen9tcl8yvLDgD9se0Lv7g8jtu0rA1j8fsgGwOwGpc23CE49iGYoEiVwZZCR6cpKiXknm93kd56fmcQsJnMezCsZu2DHeTvf9wUsLW0BqSbfkH9SprURtziIg+HmFNktVBLfO6IRZt2szzoRjg+L07m04yLRGwzPHcwLdERRrG5uZ0QXXCAcyEPVSsf4zFb1CzVW0/RZ9PePO7ge1C0h+E8K3f8jjAalTnE9CFzCVyQB0h9Zil89ZvakJviP7fdaUXMXOuIRPzZMX9T7ECypyW95tcs9T1dzGB8eMw7btPUSpAiaYKiIArg8x7INa+EdYGD8+g7PI5pcKIuSPFMAseg34m3cVTJKeMTc/qzR0rMG9NVbFY9F3wW5rUTx8iA0I8XgkFBIO8TCnVb/MT7wWCKI7cqLTKcK88UsJl+KlRN3qZH7+574yfjioE7i/8SuaCXMsuJs/iRW1Yg2rDkYZ1pm5Ls+7i/hip+M3HbJheULMTIGGmvJ5+wYF7vQiVrSlds3r5mjupbgeF5DQezK7CicnSmpCxnSZpO1hYnFqwXIYyUDwpfROcvL/dp0OwH4E/xMZFOYr35xBrLOL53RxqQJP/52e3LM5xkbDtMEoQtgmHj2JNoXndDx9GLIs38NogyzHLAup4O1D0fZSh+xseL09QScb+cdtUb+WKQcWYoM/3WpuxxAcNc0ZaRjtJKhY0+9YrlCwgOPh2RSEb/oVtlcf7muzpM8qe2Cslpq3rovC0U1vLboADtauZbmV9zcB6AiV0WpxZQSU+5FEPAz0ikaEPUW9KRT5VShkqij0yOeDOlR6uDQuBOVtgGY422sjstF4LJpmUp/Cqw6g4hEBBukS5qDsRKmgcsEFtwCTkhrXJrz4C++hBz+rkvLJPJUI7mVLSnTc5u1UPxx,iv:0Zo9ZpBGqWOtbqWbA5aJz52MQWF8+fj0CxS3bIY+5lU=,tag:O0o+0gNZ4/jrZVayiJyAeg==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKYnZkZEpXV3ovK3dyL1lV\n        b0pJOHJSdjVldFRZS3Bnc1E0S1FyYy9ONlUwCnREa1UxU0xWRFIrMjd3NkdYanRw\n        aVRYc3c4b2dZUHpuMkxvRWV0andZTGsKLS0tICtGQ0JBYktyMWtRNnlaeXZzNUhF\n        NllMam53MVFyV2dRbHBrendPOFNFZncKM729SpIHkpSMSP4UjlbzOB1Xf7UxCFXT\n        gv74AjVrTcqxXNpUT9f42rvf2uRq1dum6sk1azbyKAuLYPFSKXM7oA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:41:08Z\"\n  mac: ENC[AES256_GCM,data:oMGwTbAUcLbQgNzIu6zlPiJLg8VkR8SNDshQOQAEtNktOsQK32fikUToskRd8rfOSbrtscCew0llPn+6GxTlA1+8qVp1Vy/2DbdLG+0tksfIqSgE6MQCKjDMx74zDPIn7ZPEtU6ZA2YsoC8SWVUMShfQzAeO+Yv6RJypqvVPXuk=,iv:xTojCvCTymvto0H+PDvMROIoqkT5XfKz5GjF7JFAJi8=,tag:rHkjR8vZ0FXVjC0HLjJuQg==,type:str]\n  encrypted_regex: ^(data|stringData)$\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "kubernetes/clusters/cluster-00/secrets/sops-age.encrypted.yaml",
    "content": "apiVersion: v1\ndata:\n    age.agekey: ENC[AES256_GCM,data:T0SIW1jH/L+sBx9x4iBFLtxSuiw5h47LfgHa+qNwXzw85n4RCq0qztEN/HGon7RhDFwkkcJuNTeGim3z4SYeoh3wmdoqwmWLVSyVHaiKvvOOM1cjKXK4wcY7ixy9Qd0bIAZR2fYdGKY+baIBfWiEgajv8a2SpmE6vHfCTVf0N5vl4DXoXKdAQnWrPvqkaur+NhAkLGLpWKMny3BLPnJWlcdRD6YGcfQxyX9JtgpMIvDFuLMVdBL4KM9nWiyjP05ofFIvSa6abzmyP+TIelVUc/eC9T+zBc2loTrnS2de8609H0xSADqKcQFF3KHY3C85Mn3JI3lw8V1RNuF3,iv:Nz7dlXcJi8kR4AfVQAsNvtjB2Gsd7er+e0HvUzxvueI=,tag:dNDKN06P3B89u1f6KGYCyQ==,type:str]\nkind: Secret\nmetadata:\n    name: sops-age-secret\n    namespace: flux-system\ntype: Opaque\nsops:\n    gcp_kms:\n        - resource_id: projects/raspbernetes/locations/global/keyRings/sops/cryptoKeys/sops-key\n          created_at: \"2021-04-14T09:56:06Z\"\n          enc: CiQAesqCOZISRRQTtLQ+hwyFXhAxPjfddIigwq/psm2fijO9cY0SSQA2cmGUMUZt4TJGNgqSOPLWe7w0nfFekhINR3Q45P6KEsWlr22cZZf0KygEOufqGOnmuFZyCqlSJmmbAgiqGgx5sUgu9rIwUWw=\n    lastmodified: \"2025-09-30T22:16:28Z\"\n    mac: ENC[AES256_GCM,data:CFLqmVBffFJ0VcQQj42cVmEScTXVX078oDviNl9CSUbLLuadVZ0jXOot3iVYO3qQwUoSfh7N4S1/EIipgOcwsnADMSbMp59DlCXofkye+n1JDebOUUOd49lrI4a7krNZgk7YTVOXHZXN9IszoQZrYilqIgdmTwogRGWjd6wMdr0=,iv:sySsvWKhbZua1wkhXoy7fIqSloUOayEWmNfsJuFnmZI=,tag:W06zQglZY0ulxy1dyVtVJw==,type:str]\n    encrypted_regex: ^(data|stringData)$\n    version: 3.10.2\n"
  },
  {
    "path": "kubernetes/components/common/alerts/github/alerts.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/notification.toolkit.fluxcd.io/alert_v1beta3.json\napiVersion: notification.toolkit.fluxcd.io/v1beta3\nkind: Alert\nmetadata:\n  name: github-status\nspec:\n  providerRef:\n    name: github-status\n  eventSources:\n    - kind: Kustomization\n      name: \"*\"\n"
  },
  {
    "path": "kubernetes/components/common/alerts/github/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: github-status-token\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: github-status-token-secret\n    template:\n      data:\n        token: \"{{ .FLUX_GITHUB_TOKEN }}\"\n  dataFrom:\n    - extract:\n        key: flux\n"
  },
  {
    "path": "kubernetes/components/common/alerts/github/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - alerts.yaml\n  - externalsecret.yaml\n  - provider.yaml\n"
  },
  {
    "path": "kubernetes/components/common/alerts/github/provider.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/notification.toolkit.fluxcd.io/provider_v1beta2.json\napiVersion: notification.toolkit.fluxcd.io/v1beta3\nkind: Provider\nmetadata:\n  name: github-status\n  namespace: flux-system\nspec:\n  type: github\n  address: https://github.com/xunholy/k8s-gitops\n  secretRef:\n    name: github-status-token-secret\n"
  },
  {
    "path": "kubernetes/components/common/alerts/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - ./github\n"
  },
  {
    "path": "kubernetes/components/common/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1alpha1\nkind: Component\n\nresources:\n  - ./alerts\n"
  },
  {
    "path": "kubernetes/components/volsync/externalsecret.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json\napiVersion: external-secrets.io/v1\nkind: ExternalSecret\nmetadata:\n  name: \"${APP}-volsync\"\nspec:\n  secretStoreRef:\n    kind: ClusterSecretStore\n    name: onepassword\n  target:\n    name: \"${APP}-volsync-secret\"\n    template:\n      data:\n        KOPIA_FS_PATH: /repository\n        KOPIA_PASSWORD: \"{{ .KOPIA_PASSWORD }}\"\n        KOPIA_REPOSITORY: filesystem:///repository\n  dataFrom:\n    - extract:\n        key: volsync-template\n"
  },
  {
    "path": "kubernetes/components/volsync/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1alpha1\nkind: Component\n\nresources:\n  - ./externalsecret.yaml\n  - ./pvc.yaml\n  - ./replicationdestination.yaml\n  - ./replicationsource.yaml\n"
  },
  {
    "path": "kubernetes/components/volsync/pvc.yaml",
    "content": "---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: ${APP}\nspec:\n  accessModes:\n    - ${VOLSYNC_ACCESSMODES:=ReadWriteOnce}\n  dataSourceRef:\n    kind: ReplicationDestination\n    apiGroup: volsync.backube\n    name: ${APP}-dst\n  resources:\n    requests:\n      storage: ${VOLSYNC_CAPACITY:=5Gi}\n  storageClassName: ${VOLSYNC_STORAGECLASS:=ceph-block}\n"
  },
  {
    "path": "kubernetes/components/volsync/replicationdestination.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/volsync.backube/replicationdestination_v1alpha1.json\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationDestination\nmetadata:\n  name: \"${APP}-dst\"\n  labels:\n    kustomize.toolkit.fluxcd.io/ssa: IfNotPresent\nspec:\n  trigger:\n    manual: restore-once\n  kopia:\n    accessModes:\n      - ${VOLSYNC_ACCESSMODES:=ReadWriteOnce}\n    cacheAccessModes:\n      - ${VOLSYNC_CACHE_ACCESSMODES:=ReadWriteOnce}\n    cacheCapacity: ${VOLSYNC_CAPACITY:=5Gi}\n    cacheStorageClassName: ${VOLSYNC_CACHE_SNAPSHOTCLASS:=openebs-hostpath}\n    capacity: ${VOLSYNC_CAPACITY:=5Gi}\n    cleanupCachePVC: true\n    cleanupTempPVC: true\n    copyMethod: Snapshot\n    enableFileDeletion: true\n    moverSecurityContext:\n      runAsUser: ${VOLSYNC_PUID:=1000}\n      runAsGroup: ${VOLSYNC_PGID:=1000}\n      fsGroup: ${VOLSYNC_PGID:=1000}\n    repository: ${APP}-volsync-secret\n    sourceIdentity:\n      sourceName: ${APP}\n    storageClassName: ${VOLSYNC_STORAGECLASS:=ceph-block}\n    volumeSnapshotClassName: ${VOLSYNC_SNAPSHOTCLASS:=csi-ceph-blockpool}\n"
  },
  {
    "path": "kubernetes/components/volsync/replicationsource.yaml",
    "content": "---\n# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/volsync.backube/replicationsource_v1alpha1.json\napiVersion: volsync.backube/v1alpha1\nkind: ReplicationSource\nmetadata:\n  name: ${APP}\nspec:\n  sourcePVC: ${APP}\n  trigger:\n    schedule: 0 * * * *\n  kopia:\n    accessModes:\n      - ${VOLSYNC_SNAP_ACCESSMODES:=ReadWriteOnce}\n    cacheAccessModes:\n      - ${VOLSYNC_CACHE_ACCESSMODES:=ReadWriteOnce}\n    cacheCapacity: ${VOLSYNC_CAPACITY:=5Gi}\n    cacheStorageClassName: ${VOLSYNC_CACHE_SNAPSHOTCLASS:=ceph-block}\n    compression: zstd-fastest\n    copyMethod: Snapshot\n    moverSecurityContext:\n      runAsUser: ${VOLSYNC_PUID:=1000}\n      runAsGroup: ${VOLSYNC_PGID:=1000}\n      fsGroup: ${VOLSYNC_PGID:=1000}\n    parallelism: 2\n    repository: ${APP}-volsync-secret\n    retain:\n      hourly: 24\n      daily: 7\n    storageClassName: ${VOLSYNC_STORAGECLASS:=ceph-block}\n    volumeSnapshotClassName: ${VOLSYNC_SNAPSHOTCLASS:=csi-ceph-blockpool}\n"
  },
  {
    "path": "kubernetes/tenants/.gitkeep",
    "content": ""
  },
  {
    "path": "talos/README.md",
    "content": "# Getting Started with Talos\n\n## Step 1: Decide the Kubernetes API Endpoint\n\nSet the Kubernetes API endpoint, for example:\n\n```bash\nhttps://192.168.50.200:6443\n```\n\n## Step 2: Generate Cluster Configuration\n\nGenerate the cluster configuration using talosctl:\n\n```bash\ntalosctl gen config \"talos-default\" \"https://192.168.50.200:6443\"\n```\n\nConfigure the endpoints and node:\n\n```bash\ntalosctl --talosconfig=./talosconfig \\\n  config endpoint 192.168.50.131 192.168.50.132 192.168.50.133\n\ntalosctl --talosconfig=./talosconfig \\\n  config node 192.168.50.131\n```\n\nMerge the configuration:\n\n```bash\ntalosctl config merge ./talosconfig\n```\n\n## Step 3: Configure Control Plane Nodes\n\nApply the configuration to each control plane node:\n\n```bash\ntalosctl apply-config --insecure --nodes 192.168.50.121 --file controlplane.yaml\n```\n\nAfter applying the configuration to the first control plane node, bootstrap the cluster:\n\n```bash\ntalosctl bootstrap --nodes 192.168.50.121\n```\n\n## Step 4: Configure Other Nodes\n\nApply the configuration to each node in the cluster that is not a control plane node:\n\n```bash\ntalosctl apply-config --insecure --nodes 192.168.50.121 --file node.yaml\n```\n\nIf the `node.yaml` is encrypted first run the following command:\n\n```bash\nsops -d talos/generated/node.enc.yaml > talos/generated/node.yaml\n```\n\n## Step 5: Update Talos Client and Nodes\n\nDownload the latest Talos binary by substituting the version in the download URL:\n\n```bash\ncurl -L https://github.com/siderolabs/talos/releases/download/v1.2.7/talosctl-linux-amd64 -o talosctl\nsudo mv talosctl /usr/local/bin/talosctl\nsudo chmod +x /usr/local/bin/talosctl\n```\n\nVerify the local client is updated:\n\n```bash\ntalosctl version\n```\n\nTo upgrade nodes to the appropriate Talos version, follow the upgrade guide.\n\n## Step 6: Adding Protectli AMD64 Devices\n\nTo boot Talos onto a Protectli device, follow these steps:\n\nFlash Ubuntu onto a flash drive.\nInstall Ubuntu onto the device and complete the setup.\nRun the following commands:\n\n```bash\nwget https://github.com/siderolabs/talos/releases/download/v1.5.3/talos-amd64.iso\ndd if=talos-amd64.iso of=/dev/sda && sync\n```\n\n**Note:** *You might need to run the commands with sudo. Also, validate the block device using `lsblk` and `df -a` to ensure you're writing to the appropriate drive.*\n\nRestart the device with sudo restart.\nEnjoy running Talos!\n"
  },
  {
    "path": "talos/generated/controlplane.enc.age.yaml",
    "content": "version: v1alpha1\ndebug: false\npersist: true\n# Provides machine specific configuration options.\nmachine:\n  # Defines the role of the machine within the cluster.\n  type: controlplane\n  # The `token` is used by a machine to join the PKI of the cluster.\n  token: ENC[AES256_GCM,data:CaORwG/g2cUd1cANVsLtA8YD+jmrHgM=,iv:Z8qV+DYmiTTtZNeholi8ixcOR8yqUBvRGZAk9qD9eXc=,tag:9FAb0OijJ95dj1MHWflL0g==,type:str]\n  # The root certificate authority of the PKI.\n  ca:\n    crt: ENC[AES256_GCM,data:vHaig1m17I4VFpa3jSmjnwfOVySELh6Nj2EGFDdlgOf0mNHfwzYP6+oHQhrhSNDpEhl/4c51cfDNFxK5q4Pal6k+g4G5bjkv516scavz9V1Khs39E2O1vwem9pHHwd7yo35drLZQFoALQhYT1y+RCCiWiUtdMBk/2RyNh4FcEysy6fIdDzbh+H204pMzUJ+mVqLYKTu5VdLOT3j1lgCfKGsAV1C6A0hX8fuSvVSzzt8H7XjasaEUSyEXrtorIlVP5lpdw4G+nmOpTJL+vqfYsLlbgTt92jWkZEyxEjhu2Fjt2x4Ch5iZM7e1jgMZJ7UeHDLf9BJ+xzFXMIDwWYOYAQPnP2ABMpUMD5EAoPcOPhrm6sbJaE337aJl+Q5ulnwFcVsh6xaqG61K3oLSxpqEle9rZd8mebQUaGJ6mmn6wZWI01JahhuoeiAeoLXSdCf6ptg70qO2Ctbrkvq94PNwZzhSq9y2XhYliiD/kqf2RmGkQDqMeF6YwDLGtcEM8djPsaOEtuzGvIVC5rwfjJGOM49146IL76dDMT7hVMO0NCDcPxOQpJ3+Pq2pKfxm4K4iFAdYl1x80V/ZOv6KHzXy/Pkn+m4Q88SW45qfEOb0im+Fg/za0g5SQ92z0NqAWA8OSNLbKy0w7QMKMGPFkKVgYvTszBXkxKCt7xSqI5B4yiJRlzZIgN9MtJKpexECUiwdPT6NAjr9ALEfXDmo4BP9SyAbKyEhN+J/zNIRZpjYdrnVXykZZTSp6IThm+NI6yaJ5sM0pl39VM6DiibbLcaYWODID2kaf6mhYdTbIO2uYqadJejuqFzoB4U9U4hQZEUH3ru9VIuu2pdM+n6pnNTgmYWa1jMPDn+qLRzH9F6pt3EaJEWr,iv:NqjMVRVaUBT7rQlLHCYiWRG2Z6WKl/+QaNE5HC5jTzo=,tag:FUFFZ8o9s+v0+MExDK8odg==,type:str]\n    key: ENC[AES256_GCM,data:+f+ZKW4ZLjrMTuTIpcix42Ryxwfo0h2+5pGNXPrttCZkpEs8nv47QT7cs+twPuOoXAGJu4xmCwsE+6mMbfIRplWMobqF5tcKhW0JEQQoW97kctwSToI6bWPm9gO5ITfJNRZIFXphGCwASTBlHlQIf9bcGg73yl09iG8iw6JPY+05VQZWR1/rslrJdbI62kDqkwCrt2C8d+VJJDXCv3hjgRn6pK0+3wUc3IrMyDHiws0EnXW5,iv:pWdF7PPFqx/c4oZ3Okr+Qm38YYSkvXeaVVcgSmL4YY0=,tag:5GYF6ccetCw/N/4vi4ecTQ==,type:str]\n  # Extra certificate subject alternative names for the machine's certificate.\n  certSANs:\n    - api.owncloud.ai\n    - talos.api.owncloud.ai\n    - 192.168.50.200\n  kubelet:\n    image: ghcr.io/siderolabs/kubelet:v1.34.1\n    defaultRuntimeSeccompProfileEnabled: true\n    disableManifestsDirectory: true\n    extraConfig:\n      serializeImagePulls: false\n  sysctls:\n    # Inotify — required for K8s controllers/operators at scale\n    fs.inotify.max_user_instances: \"8192\"\n    fs.inotify.max_user_watches: \"1048576\"\n    # TCP/Network performance — BBR congestion control + buffer tuning\n    net.core.default_qdisc: fq\n    net.core.rmem_max: \"67108864\"\n    net.core.wmem_max: \"67108864\"\n    net.ipv4.tcp_congestion_control: bbr\n    net.ipv4.tcp_fastopen: \"3\"\n    net.ipv4.tcp_mtu_probing: \"1\"\n    net.ipv4.tcp_rmem: 4096 87380 33554432\n    net.ipv4.tcp_wmem: 4096 65536 33554432\n    net.ipv4.tcp_slow_start_after_idle: \"0\"\n    net.ipv4.tcp_window_scaling: ENC[AES256_GCM,data:IA==,iv:d8fVhbnF+Ue4+8dM4LPTXWhAHV4FH5BmwBS8V5KGzco=,tag:nqCJ0VYb96NDHpcH467JEg==,type:str]\n  network:\n    interfaces:\n      - deviceSelector:\n          physical: ENC[AES256_GCM,data:jsxyww==,iv:brQwInLaLSmJLi/w8TMTBOF04mpLOKModbDfXyzVgJQ=,tag:QKkEEvDZ6lG6L4Y1aw0hmQ==,type:bool]\n        dhcp: true\n        mtu: 1450\n        vip:\n          ip: 192.168.50.200\n  install:\n    diskSelector:\n      size: '>= 1TB'\n      model: CT1000BX500SSD1\n    image: factory.talos.dev/installer/c9078f9419961640c712a8bf2bb9174933dfcf1da383fd8ea2b7dc21493f8bac:v1.11.3\n    wipe: true\n  registries: {}\n  features:\n    rbac: true\n    stableHostname: true\n    apidCheckExtKeyUsage: ENC[AES256_GCM,data:AVoFYw==,iv:VFjONzVhuz0byvxRcMMovprGLhF103cgJgt3DqnrAKA=,tag:0khRMyZta7vphspH6MBW7g==,type:bool]\n    diskQuotaSupport: true\n    kubePrism:\n      enabled: true\n      port: 7445\n    kubernetesTalosAPIAccess:\n      enabled: true\n      allowedRoles:\n        - os:reader\n        - os:admin\n      allowedKubernetesNamespaces:\n        - kube-system\n        - actions-runner-system\n    hostDNS:\n      enabled: true\n      forwardKubeDNSToHost: false\n      resolveMemberNames: true\n  time:\n    servers:\n      - time.cloudflare.com\n      - 0.pool.ntp.org\n      - time.google.com\n  files:\n    # REQUIRED: The following documentation explains why these are needed.\n    # https://spegel.dev/docs/getting-started/#talos\n    - op: create\n      path: /etc/cri/conf.d/20-customization.part\n      content: |\n        [plugins.\"io.containerd.cri.v1.images\"]\n          discard_unpacked_layers = false\n        [plugins.\"io.containerd.cri.v1.runtime\"]\n          cdi_spec_dirs = [\"/var/cdi/static\", \"/var/cdi/dynamic\"]\n          device_ownership_from_security_context = true\n        [metrics]\n          address = \"0.0.0.0:11234\"\ncluster:\n  # Globally unique identifier for this cluster (base64 encoded random 32 bytes).\n  id: GsSf9LerhTOpktH7JMlySUhdB4tdxlX1b6ZDGM7a8ZE=\n  # Shared secret of cluster (base64 encoded random 32 bytes).\n  secret: ENC[AES256_GCM,data:NpRTLs9PVOUcW9UTdTzhcoxbfLQaITm0lsb87eYtw5N6483cfl3Sx0HtCbM=,iv:mYsOdIxOzLowdl+1dpd/PAxBhZ85stRdFPS3+WbGjBk=,tag:oGdyAXj95QRMWVH3lydH8Q==,type:str]\n  # Provides control plane specific configuration options.\n  controlPlane:\n    endpoint: https://192.168.50.200:6443\n  clusterName: cluster-00\n  network:\n    dnsDomain: cluster.local\n    podSubnets:\n      - 10.244.0.0/16\n    serviceSubnets:\n      - 10.96.0.0/12\n    cni:\n      name: custom\n      urls:\n        - https://raw.githubusercontent.com/xUnholy/k8s-gitops/main/talos/integrations/cilium/cilium.yaml\n  # The [bootstrap token](https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/) used to join the cluster.\n  token: ENC[AES256_GCM,data:hn3MsTRf/WzsGsAvVO1B8yItz6A9ExA=,iv:OXZOKUHnvbFg/JOj5ZDZOCIOJy89cJzXR/+1Qezryzs=,tag:JSvnBK6nsqAlxVxBfc++bQ==,type:str]\n  # A key used for the [encryption of secret data at rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/).\n  secretboxEncryptionSecret: ENC[AES256_GCM,data:Fccm0ik7CkfGL4H9Qnz/tIxWG9deCES0y38QDj6b3byerNHS2lx24UnVFmY=,iv:/ga4iFHoEXET39Hl4eIGpUlEM9PuE437sfOW9ycezkY=,tag:SLI32h8Jq7YUFf/KNGRYCw==,type:str]\n  # The base64 encoded root certificate authority used by Kubernetes.\n  ca:\n    crt: ENC[AES256_GCM,data:bfJ15RpcLIpHFIkNlf9R1U4I1UCIVNYl1QKItVLVjiEQxxT27BcgIG0l+DJGwkG60E+2ZDWbYmjSVB9BcFnvR1nQRmqDxejWGg0ZYfHi/pyiaUcxdjqUgNSG3uEmOurbEVJ0NTs60omg37YVShXztgNm5ix6xilhBp+m8NoA1YA1TAJTBa5os/YJhh0kRXvDN+VsII16beR5FAoRjCmDuqIU/FYsyMXfN5+l9HXFwYgax76JTpzgtBlzDEQWo7KdwQh4Qa3J/rN566/p9nRo80NFtchp7OSg5g4nl0ggCbPK/RJ3LMhAEzS9uFcc1roUDT2HaiRoZGRY6jHZGNnWW6hIE18NoAB4PjOtFgMby7Qg6e6Engl5EdP6nBh81qil15vnBZ+sa/1HTUWy4u46AnJRePNSV2Mq1Y67O6cLwVHkg44mDa3UZl5zMB8GzoO92Y3B0N9mHzDVhXal+aThsHHT5dC4JZEBwX0dlUls/vpYoHJ8MyDzNVaL1CN4E6Oo/01l54Ro58ULrXKRRfq+ac1r+fyJ0UbQlnGG4vbJKwPeG9uv5xAvbYhFH8Bt5OqVBMzaOEut7mbc+lIGIySuGq+hWkBtIQxNk0y92f5vzWSaitrAR678rYG8v+1Jv4zlglnm4qFqQ+uDLGogXy/ZrkIR9J26/BqHDtTURjVRjcO654gQle53OWJRwxMv0L+d4ET4q9Wdc1LXurmlVnBrfbGD6OzSfCoyjq/dISllevWnHAVOdnC+pvsFICFwc2Xh9sNVABJ+VWUfiXGibo4Dd2kgDMpBN1n2uG+wct/USGxtX29nyR2++5T6hABWA7kuMKpuWhx6ujwuRd95+/B80m0qiM9X5FZ0C8m9Zx3dHj2tmfLDhrni8Rw4jF7YsAvWe0xw1aPzjKA+cCOegYgdqJo8gkAEloOH8c3e9lj9TkCOFutrD6hOjonSKDxn+Pz1Bg8m3aZlll/pun+TCCz8PzTvhCqqJwanokBxjv8AuIxP7hrBK3gYS+thcGUfziEYETHmFRFxY4BXe35VDU+x12CmSZ4nA69vjoFl7g==,iv:x7zcTfixH1DMNexaAA80ZeGTtwOJTLHZLOFtTzzg0Lw=,tag:4MmoRAfh2ZqWIWbdnvFoCA==,type:str]\n    key: ENC[AES256_GCM,data:Sx+CZU4TNHEon6hZ2eUct6m+JSFlf8JIdCREdgTXMrbKuiH+FBcxHF+OZFiBHp1S6+BygnWWwQVZcBxvW1IQulZD9gT7676qWJnRC3ZW0g36uEykO0CmuYqRWxbdIvC/7EmBNA+m3XVkm8QWp4uLdftLoRhVdEgYvQSEbGS0fkgIOJL6eu/FYwsAB8EMFpuy/gS/rL4vu01A6e1+srrSHoG8cuZnusu1J20Dr4laODJDMOCV+NcWFKQsvJUPxbWiNW/ZQLUkWdGxH0xaTb3UyDG3tjDD+KWULRocJfZBcWNy3a9j01cdekyBlJXBpk1wfyGU5PhgszxJ/+Od1mxSmx1jfGJjCLz38bPMshUHNAPUhwZAYwELnCZhMhQdp2qZn8j4oluICkFM9s3n2OLjcw==,iv:qwGvuFYUl2nN87DMG+IsOZdOy2UnimcMZWQQtpabbRQ=,tag:5cKeduMKp92gBi+VakEIww==,type:str]\n  # The base64 encoded aggregator certificate authority used by Kubernetes for front-proxy certificate generation.\n  aggregatorCA:\n    crt: ENC[AES256_GCM,data:mW+5UMH9NlpO6S5HBJ832XTXahhQFZF/dXwuErlEXv0VIfnZPSMOxS94Sss5xZwCxGEgU28DhyBShXlIIbPmI67jdDvLnLao1tOl9INwtjYlbYP2oYUhLgNaDj/5eFMadua5QsViJiqQcIvkg3GVAzK/piCfcoJE27ATJbOh5TZumD9Wc/cLveWisEf9IiTXVRbBFNe7ed/vuVVWIdT9XFuLr/2lC0xLRUk9MkqbQX6fypwa61WfyoPacO++oaATYPUB+a9MPPfJ5a/ww71/nRn/mqmhMzKbgL6ZNmcw5V2Lmd0pJukuOuXgPOPT9nZaOnDGU7knvT3RQ4DH/NWsjGa2pirvSlRkHbUUzTNwk1y0VjwsN/xeV/rzqir0ZmuVLIBiSNKJwOgPMH0yZTphJLhDRSclVJGlpsbcRzaILJGzosbU9WfjSlYBsmjvTEL+B2J9pZWCVWwU2QSxOWuhqpyYoUDHzXujYpn3t4FDgIV10i3v0DKyYMcRTKnx347kUg5sTMx/4cVIOVMwF3FNGYAeUR6OzlU+0si9braIxhdJo4paM9J4StBxEyU9y9xgkPkXsJ4z7evGz/CRjCEgCS1PfQ/Hb4LdnMBCHbOjNAsU8K8mleyqPSG5ILExgzN3hEbdk6keGplusXg98+yH3ZSrtOBzB6M3T9lduJcx1GUNrdrLGZLqz/1w79AYc2R7ICKhsgiGl0T9caKszZnq16NaAkoM8r7IPMTWKBwAmJEG/i2scuRonfxYo7xzGSn43tETQktLzbcKuCv3LZW4RE0ZCI5Xbqz1iqtjZWf5ipOrOhaU3sO0eWncXNbxhRBHI/HGY214wP+p+KW2CkYbS7MknykEclS7yROCHtL2oe4wsuYRuGH+Tyxs/WH/T0OZxqL2kU0TKctO9DroMpIy9h4Bj4ABmM2jR65mH11Zztx5w8b9ga2nIUHXxFGoDcO7,iv:6WNApFnrwFveSNNzsiW9WHXWcvyjGLIBfLdCm09e9tc=,tag:QDWw9rsx4UpvwCOpQJhOtg==,type:str]\n    key: ENC[AES256_GCM,data:S65KruU9QYJBsGjWI1tCqX6qiVqM5w1orY7X6zxxVSCOvFwCaOvWhn9dPrw8TIlbhJuTtTquNX/QR0PkXO96iGXkPIr33NM3MlEgP1S/V7FJRWOuPjYtwBwmpoBm1rUVaC1KQHGZAJ3/P9ZciDpkwgEqPjpoLNOGj2Jz1qD3IqbwgWgqs0q4XS/xPmc+gffiwm3Wbr+m9jEo7zhjzAJEMWD76V+h1v0Nju/Ip2XdSaSx+9BhYNmWOCeV/ShfnUx8vILzEvUC+zKpsoQWxabB/mCtwgygddBUxHSkVyTw7B3SUlFa1khysoS+V9K1iMAzcO98hKbM176xYp8VKrH0nDDeeJcKc+vx7Sbu1GByyDmwZds69WQy3ntnj986dqZhwHMSfy8jGigkqwz77tQz6g==,iv:0mWDy+hGOA67vobRV1Wld/2E6rJ6FyxWS8JEnY6Bk5c=,tag:o2t5Vkpd6hziLndxgNa2+A==,type:str]\n  # The base64 encoded private key for service account token generation.\n  serviceAccount:\n    key: ENC[AES256_GCM,data:dlQoNOfe/x5/KgdOWz7VFB+iSc3GguA/srHBZs5XNKrb/NTjdIgXribBFBo8DRDBT2wUqvNU6Pa9gn6dykCPk3Q71Z5ANcWyYq41tLhblhRGXIVNTm08Y4G4P8kHIialLqUVkum3FD1rO8r1uO013VolZpEbHgY1GmOj0ayY50p5Ha6uB1y3u0CqtOdFr4WFQ23QunRahOU+jrT1LjXK3NebwYbITPq+U76zOhwP50mizU6+kfHFHlr5g8eGFZPT7fTxAYS5uuwXBDRKQlmbDg9uq5aaRrq6NgfKe9RBcRZ8sr7xQDF1O+lW+eUFrekOC6UX1nVVxVBlVZmX5BTMA+qX2Ec1iRGmZ/1fewFKYcCS7BeyFbKw4LSXCRS7TbZ9z7gtrRs41YpziQ04E2aq5wFEJaHn+g63dREBnvDRM7OMrSDjy+2OJNznMIxZbeEdn1JU1NzZFM6ZpMuIfnbCaKx0JLgd5H21Wiyk5NasInUzCMRLpdSx45wowKF7u9nhI7h08LGmsIttTS+mHWOdmh4KvAlnaJPPZx5vHPEFN4H2GVq5BNSlADJ7U+jrhM4xL/ursxuFQYUhXi685dzJk7Kk3w/hdRf/WvuCl2zmL29Q/QCK9pMIyOUceHUC4vEDs7GBqyUSpEQ0jAd3tTKkHGH+Z4tJXTn/Kx2GWbA062oiGvypZ+zZ7Zi4o0yrK5hLeFfvnaAtq5/5UL9Oz8Dj3JpMlhAOqlCvJs8UOZWFtqvrUX7u2V5sVAFggmNCmAkvdd5MgDlfqz1r32Iq7YcyQK2+hOS0ndXmEYsklFyfjYl681Cljel2hG4Dkfz+wsK+z52fhN8FO3gp4j9C3ArzOLvbYEEiVYHvug3X8w6vOul2oHhHSI9Yb0mkE8FoFD9l/LhBobSn3UpVgHqPbfptmvEduKTTb61AVKcLDcDGE9zWGBV4RgLGCFFVVkuQfXJNiSic3qSnj1mD58eC/tOcXrteNqPAPrDvK3Pb8j88Heyw9Gi3jWGKvEPmCMtJmUct0qwy7LIp987YB/0k8q43YlOZBNfn/0xIYFF/5MDsA6cMJnK4ZfjLpcBgUFdOe5mfKSnfQFyNZZDh6DHEALzxLmJBb3mk6M6hKK+rvTr1kv+vcQw+fbcwbuvvuXj4hcWQI+8R33OydNqsJN8VTqvc+/H2mA99uD5mCVdNM+adO8B+GVETCF+hmsgJpoS+vUK3Hr6pXX7oRqRN/qfwa9hhBpSDvZS0JMMyAokKppTzNvxIheJzzOn4HOG76c7phU0+oAoNi0B6/LSPjWl/LucHEiQmcV42YNlucjvdAfImTHMi6aF20LNqPpTiTED0yAQWhGPtOD2d5e18X3+ayS4JX1xjsz75yDZyK1J8W51UPy1WwetFlJexfy5ayc7MYFlCrE2bJTr9wgw2QDPDv9C/oUYtNSPbXDbTKrSvRCfAHovbXwt5KTHfX6ZHMQOSKYETlhMyA0aQpjScnMp/uJrI5wGzK8HB4s/ye5YXRrwy97aRlfvl0X2xLfL0eTEXNKXZ9a8u7kwjrMp8dfuuEcaNTM2Qc31Qx/X8wukcMC/UCbD9l/ByHqdfS6r2QisixL+MsJsVb6O8zZYfnqvSQGE+cQ9RRjLkZAeoCWYTcPIm82hgEjK9jw+0zTbPUWRQVCty7+SDaCocmHyjOYgxh5l0EQXTBVUKKgflyOQtrh4IdvQFj4hEV999X8eMqJOYIvCeuaKfN5SsY8slG2z/hiwUDdZrBtzuJAZNu0xl5luSYfgbHS2RGx0mv2XysqNE5l8qQbXqI6INrXw8bURPsPUxqmxqj0vTC0HSrR6wRMnkY5qIRdpf+4UBkIrJJo1EbEJQ4rtUwpgUqUJ08rJvuwp4QP/aXnlaNIAdGCqu8/7Akq3Y1gl3mYBPY1+CYTgBMwpYBxu+UKK8XWYjOjgsVS1TCiLeXV7s/cUijKslG5907PaedDw2TEQXrdub0R5nmwcvLXrSx4q/VLlbkDJf7eO+rpl7wSDfFWFy4aEY76MCGysc8FkleIKuIZ9pDnIJSMclPXnZ2zfNi+yBa/XGmrt0ARrvVNn3YC7hFrTOX7eU5Y0vQTBePZG4WQQ/C53O/Km1U5DWlVKjb8dJN9PwbP+sKlOKkRH4VWW2zQSE2MQzAbk/IYuiaRIF+hmsRa2LlyPgIoEUYYP2jjvesG1ypS69JqmQKQoVKd+JoMqDRIRRdqeELd3fKFYYEjsBUn1jaq7lVN+Ec3llSQnWwDdaVf8nVu+BCfJp1zUr5zmm4a2zaF2/CTdLRlzkNtFUjQattFbmp+9NmvwqOmujLsrM711sJn2lVp9p/DZMeQbBdXK48maxkrSSui8io2blqpc5wXVX8Kfrl5baQcbSMTtlAXbj/FuzCmH9Sm1dLbVXgVTBr5cwyupSpD7/jt6SdYW5hfbs7zW5j1FWfG+hJ1d1Mh/TIOSx+sPn82ayrL54dYWj6MPtM9DPcxdB1N7Xm6sz4mwY+CdNTbHIRJKjJbPVqJImN5XfCnLkZlyyx9VIxtPxJTGpdvraVHnTpHSPNAZ7TR5nQu2aN5mEeyikRDFwGPQg0MszJ9PyfxLp5Y//achNzfg+BoLK8s3wMcwGa26Zt7EDCL35r5aEs3khv4lPxeOo9I+wTtS9SgVAXeXPMHn9FdBP/gwoQPweAKpCgKtbu9WqZqoTTch6dJpwZUyQHfnMjx8V5wTxvOX2vvGeL90ftWsfuTVLxrKvfEqFHiplVe+YmhSSDK6bIqhGsFrNsaOMfJtzsUvwlNgIFmvbz32mKMGmGmJHlpiN1AGsQi7uJFOj5mTK8L1XA7hzsMTX/G30i9ZXLzRTMeDtA8omn9sSMB92cgcF2CR5conOriCH3StuuWOo8eNxZqi4Tyku/LwXj0g1pibVMmC5l0oNrXz/VuXO8U28O84gBf6jo/YlXFEjlplxND4rnWf30QkCxVP1+WjhJmHR1XF21//irbRtuYmrMHUx0X92konM4cwwXKjtRguvKM7M3BP9oyrXZX6xpEMQdTw2BRT9afXcAuQ4rSGmDaehhf9StYL1TZ9aMqaXIRJ7AcFnETAKYixNobeylKmU+9GGdEl1xAMnWVGtBWSbmftKdeVlTZo//cVTqBW7M+b629DMxz9VTKm8skhF4PRc4D0IC0rhOLvmsKyOEFrP+vRLgMhyYCpvYnWN8Us479RtXyky+YDRs8cCMDOPQdIYSVPAHSjjlHa9KApMnFLNPEWSh78bSOKsy6rJans9cTOTKLw01gY90Yz+1VG24w9pXYYbVS71DVBjks+7XnKwqaqShALG4VGtBCnp2pQbOszXpcoOHUkfkI0+xrSh/ipHalW6cp32RjS7lD5BCVBOVJz7kn8KOkDu+gXC6vufAbZXevNoSzpdZWsWj8p37FBFNyTPGnS7OcNof/vuvXpqw8ELTp3bgKqzm5hZ1sKTGgKc3O+lHIKYc3mjBYRuX3/6uvFfmQUQsh1/t0DxXNK62gzlst7UpJ5pJD/15NEM52v//xYlhpaC43vgUVBbptn7+aZ6K/hfwLXDNnsuxycd+cq4yOlgHfZJW9StAEN//VP65gk7YuRJF17Jb2/XvePWpR5MScKK/znRPIqhuODxr++cin8jzU7sgg7yIZHP0amSQUL2GWTB2dBbgJw+WRZt4gY3bxFIKgXxBGrIqjzHsZu+1NvPXcJEOcwsgVtB8eRup28e7gWPpre6ailZesubBQ0k7IzUNqNIBVh6JCX+ViTH4SpTs+/I6qZbB9Fl0cl9FOU41GCpXsbJciZM9BxMKhM60SgBPOskxU90cRrrhSUrXC6SM/rz11mN34HEtxZWAfjwTI+vUUyJ6EIsOZYDtYXNdOvQD0DEmzXIK/w5I+7dV8oLLMFE0Fvs5FO9ggqgltvkdR6BjYM6S9+pbtMDb96mViHWTMZZXqO0U+Ljfkfb/798jiVunaHVPTcaexOzk/g7nDMjXkbU38DVMc4BcGvr0MhWOdurvp1mLBO5/sffpn3D/FuMyFrr25kttwZjrL80IDyKuhtO2/GUATJP5M61QmrfiB5DJYk0CC9qwx/JlPvWw1S2b/QS3lrql59IQXdDzFIBa0xBhKhDykW9Ta+Fc9NsWwKUzv2T486Ut71CKtedDHy1egfljNNLPNghzeBMXL5cyyecbKSi90IKb1oVm6afrK3GExujMfcW1ksvYmKn1cyjSv+hEIL6RPE0GmrVfJ0Y+M60nqIPguJM/jFx0LPVf0W+Fg0zucefJgSDBO24yCssJV7bZVR0vwKUJj/Hl/14Q4Ty1ipTlJ/xA5NkPSfpkSQK3jFiLhVt5dKiAsMTcFydeykuKfeAJTu7ugAjAxlNmZenaGLNCcblysA6cnhYrIBybp1rtXYVsM9LWyPAYNKkKvr2VlAXcIQrS/UZIzLLybbsBg0264ZhC3XlaVmn+a6SESHNAXRl3tIHj8tHOoIi7OERJe2ux5aqisg0deTCQzvmX/jnOVGowvYc7Q/3qFpgG6NflKeB6dTUeH6Lzk2XmmJDSz90JGDbLMA3AEKOh1V8wGinNjalqHQhLXTy+ot7fPuXkWClKYlQ4cP8COHCz5fwSEdcKBid11BmbeF0e79fzeBn4WOeChdnk1dM1jmA8kayAsoU8CVfrQ92Rfljl2QqRAvjinnvwKluhYLDNx+YlrurnAK3tcG6Wp4rORbU6OuTClti31HWX0m67dm1CyMjVEN2hXTEP5AxwgcGK9Koq6UWmeYCjH+MSHO/+OmNt5suqAHz0rpA8ZcwUmYeEY7x46Vgvb2wpALTDJWAFmV5ooPt/jXlMNjMvfUMkDQv8dRl3JA4LMXJTXpFS1dm3q0LvFc3BghvDAe2HFK6B2tzEu9UcBf5tPQ9GTQTh+nwr1Lgc/0/C2LJZuWQmRE0kwEqvon4FnQy7fy3JT+kV0CGMObC84GgKxg2KptVKw9AyD48tY9+ZoZjuDRX5u9juAUeXF0/eFMqGgc217An2X0O05j31Loj8Dk/ZL9DFAFjDcAwYGR1BWcoMclpHpGVIY0EcNF1XI2t7SnNklmcSaO6IcPjE2o4IYuEXS9WONiMkWVL0fRKkybKXGLlbD3YqpmEKa1Jir4y9DtQ+A6ev19aXgu7eHZwa6vjaG1HvyYfSbS1Dy/oswopG3TjnG1VbLspewjDySQUR9iEGjekfj+myKDswiCjBw++t6BvvCz7v07wZQDJdGmDGqnQxfjXgrrEtpfJoi4oS9TsUM/hyE59ieY1cj5fJgp9nwZ6nniOjJxjidXBuqHiS2ZtanJ997TbvEVM243kcmFskRUR0DufD2TyOsODSPDldQ5XMunn7gOlcLNqX1lHhz81ylaR5mhWQP0yc7YDk4qhb7Uvg+uf8QNq6Gxq/26y43uhgZVvKjCwTcU8iUD8cJCPuJKrEvhz7xZ1NTZ+pqb9UcjWZLpYa9I4ekuhQmHSdldn4DSAy089Id6s6n5oJdrMke/GaTcD2CTrlljL4fOkgR0tp6hfvmzEwYE7zzBxNVaUWxT3m9Au0kxem/66Iep9RVZJwepE1LkhNZqmYVB3Ndiy+sU0uL/tJhmKLBgA5yqWepS2ytByApIkAAG/k8YuwOF4JjcAhruuOKORQJi5JKFXczZlcrEbl1wE+T19cSlXYwfIzSXAKAmq3V4yij3hRYR0UVPzof1bRkfTm05/WOuZqopAW7HagkPExT6jw64FC1xL76bX9BChDibEgpDsks8T74wvO9Zbzkqs6w==,iv:USzisipBcVIQzfHHcifPDU49QrdgLolJDpPe45YqM3M=,tag:FlXtRv79N+RoI7m/N7Vhpw==,type:str]\n  # API server specific configuration options.\n  apiServer:\n    # The container image used in the API server manifest.\n    image: registry.k8s.io/kube-apiserver:v1.34.1\n    # Extra certificate subject alternative names for the API server's certificate.\n    certSANs:\n      - api.owncloud.ai\n      - talos.api.owncloud.ai\n      - 192.168.50.200\n    extraArgs:\n      enable-aggregator-routing: \"true\"\n      feature-gates: MutatingAdmissionPolicy=true\n      runtime-config: admissionregistration.k8s.io/v1beta1=true\n      oidc-client-id: dex-k8s-authenticator\n      oidc-issuer-url: https://dex.owncloud.ai\n      oidc-username-claim: email\n      oidc-groups-claim: groups\n      oidc-required-claim: email_verified=true\n    disablePodSecurityPolicy: true\n    admissionControl:\n      - name: PodSecurity\n        configuration:\n          apiVersion: pod-security.admission.config.k8s.io/v1\n          defaults:\n            audit: restricted\n            audit-version: latest\n            enforce: baseline\n            enforce-version: latest\n            warn: restricted\n            warn-version: latest\n          exemptions:\n            namespaces:\n              - kube-system\n              - gateway-system\n            runtimeClasses: []\n            usernames: []\n          kind: PodSecurityConfiguration\n    auditPolicy:\n      apiVersion: audit.k8s.io/v1\n      kind: Policy\n      rules:\n        - level: Metadata\n  controllerManager:\n    extraArgs:\n      bind-address: 0.0.0.0\n    image: registry.k8s.io/kube-controller-manager:v1.34.1\n  proxy:\n    image: registry.k8s.io/kube-proxy:v1.34.1\n    disabled: true\n  scheduler:\n    extraArgs:\n      bind-address: 0.0.0.0\n    image: registry.k8s.io/kube-scheduler:v1.34.1\n  discovery:\n    enabled: true\n    registries:\n      kubernetes:\n        disabled: true\n      service: {}\n  etcd:\n    extraArgs:\n      auto-compaction-retention: \"1\"\n      listen-metrics-urls: http://0.0.0.0:2381\n      # Raised from the 100ms/1000ms defaults because this cluster's etcd\n      # data lives on Crucial BX500 SATA SSDs (DRAM-less consumer TLC),\n      # where fsync p99 reaches 127ms and backend-commit p99 reaches\n      # 333ms. At the defaults, followers cannot commit heartbeats in\n      # time and trigger spurious leader elections (12-46/hour).\n      # election-timeout must be 5-10x heartbeat-interval per etcd docs.\n      heartbeat-interval: \"500\"\n      election-timeout: \"5000\"\n    ca:\n      crt: ENC[AES256_GCM,data:dGNp4/kIxSZjYRsY2a1jX2F5ZkuUkAvlZ/218YeFbNb4ViUO7YMTGXCpg5/RXfk0bLXRzWJwr9fU8C6QVbQ6Kc3TdHsvDnYXgNEkdFo8O8AwqrN4smFTbeEGW+m9No0ZfejuHKgbIj52JXqFC9duRNDJ7sAe3V+rnYK77bHJsDNlty7KSZDcTAxnAohOYKryXjHG0vnfjua/RK3Kl1IJn7IVtnK0ljS38NKmV4z4dlai57D+SlaLeeqMhOPvPROegOMPLAAEPflRdJ1VzWR3eMAOK4UrnwuZxdTFJm4dD+TuVi3urYW3zsXDkns+GKVh7POOcU9E6Ra/kNljjlJRUVzN4zG7RHl88/JYraR+fBjAG2ggvkupCp7f7D53t8JFWlKEeGeb24Agw3WI2mSCLqyXuKDDrN9rTR4KkVImI9F4B0SeTa/gpkzAJN7dRw8qoeyRBu8uMIij8HEjaN4IgYXMny1t/ymIhBoaOGbW2jWulapXLcXbiJdUZoyqnl08I/G0qgB3mSMf1b1PfV14PwPVOTkPD5MBVdev+q4ajupnfFqql3HIWTW2OOh5a0cipj3PuK90P7XwN+dYBIUDEjb/nVnsYqThQ5xAfAZjeoquiW4f01mLOUIZZ43Mb/WcNaZylFmfe3JJDDv1ObcsLNlAPRL8LcmsaV6GfwtgVPfACg/msEVl1vKE/9+cOsYrfJNKpJN6FNxZre17pkH+qpXwxRtK36SLt4mhSWTk7RUDnWlrO8Z+9cuKdEmqDczQMW+HIDAPHXZ1NE0O5vSciYXAKnEqObuHvOPTk0zs8Ce9bgQYlhhr4V9PHe8w+TMCGUCeNwg/lr+3SZyi+A7gTMO2+1eyx2ORvz3DBIo+SQSx4XNbKS6m3FtRGfse6ds1cgStdimvc2zzyd7rns/iKMPOXJplo2Ywryzi/rDBB9NJpqeVIeqhf8+rTjeR8BN0Psviy9CdFMHxUpu3A9KBhvTLVAc7hIE6Y+ml233CDzdDzD/sB8Nvs9SMTdvL7zei,iv:2OGAroS1xlxrfpYeT7C2VBvFFdnTJgSbdcvADGA324c=,tag:0fO8I+04dx2xycvUSsFjWA==,type:str]\n      key: ENC[AES256_GCM,data:Wrmd1Yw6031zKraKkozc10JThkzlBMPNS1QAPqjew1V/tPhz5Lgq4ATa84BFjxLL3LCtjaGppuxPlo4exeoefZm5YbVcmrr9DmvfzDLDMdN+4B/NTk0KHQGzxw6mpfqVMWqWNOiLyY9iUlsgkFlZ30MH+9sOSmMlECBADA3enZygalxoSWHP0wmEBV3ebLmaZz6lISmgLHVQjWG4DW3qlW4q08TzU9lel/mqBVvKeJIWFDNNlE7DKhRqDvNpdtCRKEXx2cOOLzZuEqhKmeFgqJdtpzxK0Bt0yKBCSQbmGU4GoWtRXR+VDk7kfsaP504LNBOKuN03eoxVnaQg6r+qa9HENQbhTDHcTUPZEC/R+Lwek9Y+3TSP2DBGuZNNCplYIRK9LmTXgdSsPIAJOJuY5A==,iv:wnPsQ23i+mbqPWwONHPgXox8yT+Kvjj7SZ40d4+Lfig=,tag:4IlavwRghMnRAfvd5cF/jA==,type:str]\n  extraManifests:\n    - https://raw.githubusercontent.com/xUnholy/k8s-gitops/main/talos/integrations/cert-approver/cert-approver.yaml\n    # renovate: datasource=github-releases depName=kubernetes-sigs/gateway-api\n    - https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/experimental-install.yaml\n    # renovate: datasource=github-releases depName=prometheus-operator/prometheus-operator\n    - https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.86.0/stripped-down-crds.yaml\n    # renovate: datasource=github-releases depName=k8snetworkplumbingwg/network-attachment-definition-client\n    - https://github.com/k8snetworkplumbingwg/network-attachment-definition-client/raw/refs/tags/v1.7.7/artifacts/networks-crd.yaml\n  inlineManifests: []\n  allowSchedulingOnControlPlanes: true\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCQmlPdXJ0eHI0b29FSTM2\n        Unc3TldKVGVDdWd3U1ZIeFMzTlVsSEJBM0RJCklHWlBsS3ZocGlFWHFqK1Zsa1U2\n        bEZWVEhYQS85NEFUOUo1TFZlcFBBNkUKLS0tIG9CN0gzWFoxdnBOOEkyc0ZhZ2c5\n        aHoxbU5sVFdFUUc0MHhMeW1oQ0Z2aG8KUtfI19ZT0BHjAdBRzIjujpJaVxwIpd3Q\n        gw/91gb8ePG5QuXhUBS4Ql0lxJZQwL0eCIu/DgRqtkQOFve4bTrY0w==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2026-04-11T23:16:34Z\"\n  mac: ENC[AES256_GCM,data:qVE87d+yefvr02seo5/PSllpHFabU/6FGodae6Fq7Dti+IH+nDWNk3oNjgMtQ9LiCfjHbClaNc5RuyUVukGSE2SSJ3eXVDL/2gWlv/6cZ2UWmVKg2cqr2WO5K7I3Hv14S2c6eDvEfVXCwTAjG22lwQ8/bYOiW5c/gRG4Nm9JXwk=,iv:Z/U6wgdgzsxpxQZExZuXqi9liLOdt7XSw9i8cOUl8Bw=,tag:R+X66Dn8WQUC10yps1I2tg==,type:str]\n  encrypted_regex: ((?i)(pass|secret($|[^N])|ca|crt|key|token|^data$|^stringData$))\n  mac_only_encrypted: true\n  version: 3.12.1\n"
  },
  {
    "path": "talos/generated/talosconfig.enc.age.yaml",
    "content": "context: cluster-00\ncontexts:\n  cluster-00:\n    endpoints:\n      - 192.168.50.111\n      - 192.168.50.112\n      - 192.168.50.113\n    ca: ENC[AES256_GCM,data:JOIq3osnDgXIJNKmICED+rE8tZKgKgXQ/Wkhlpq7OMP+yOmzLjAwWMmwMqHoKxKWkMBmbPAAFvC1I7nt0ASiAWlXz0HcPLfgoLF2xol2guumX5VfU/R5hD8IWlWQEG6p/bR+AQuhqpLWWUR9NzVgGmdTYP4MKeOubtvVKXMCtNBY/CRml6sEyvFodLqvwCE/ZxJDDAjMNkZLxwzsgM0D3ijIndS9Rkma4yZ+knb5NIp5xjXwTH8Siw3ae/YXvDUZVxphh/KhAammp2dOYrY6AuNPc/ktNt9ruxtkN3x27+HTlsgpIUxEYQXkVydjtyPM6zuv6tuQUuCDFkJxBM/6Ei4bk7+eiN+59C7ik+P0eqy3B3ZxYdgKnF3l4wYw8g2/FPfwSlLtSJHYEPEgYRZg80cT570JPHnSA0lsohf8lYyPTjMP5ufe2WMWYWEFwrbFD0V2KB7jDqrDRtBRraCvXJ/i3ozItoNEtgy8jtUQHzP8ou6PFaFI6x28v361+LYvBgAMkFS6yijdeEpqIdF8S3yk/zKYQod/orkghl2YD/xp1A760S7NLemKiymrPzmKpEBSHdpgk5QZdlCMlIWCvF06j9+4Y5DwtpQ+RpK+R6VbsxXcrndLqgEWUCxRPxdZB+C4Hz/tmVkI5ZBdODsv4HE8IjwkFB87lbM1YSQ8MnkuB8txfhY2uoD2+h1DDXuFui3HquEMnSTgQumxGXW3afyqiv3UzxQ1OSRNmikTm3A22Ge6BJdMvCuadorxSXi/HcpOUYZenGKTtP5lnQCCdI2BOarOTJZlJDaBSSN1+qb6UF85jGuqCvSDW8m4rRW17Btktu6aOj6PA00tEl7+HoUbrjTG2O2dM0BJNVzA4ipuPWsV,iv:ywNLgj9iGSFL2ZCH3kaL5T+IZW1q1taCLqqz9DOA9Co=,tag:XuXPu3CQ7shVAH4kM41mqA==,type:str]\n    crt: ENC[AES256_GCM,data:fe7CuwKhpswXNhNr2lqN+4y30QmOgcEssa3in2qP88KinkvxPRUalHpom6OYSKPn+eAEK7B7VwVxK++Btq0J15yV9tQS0D3KdBasJrsIialsF0+7EB5XXq6kEfUnliS+K8T9iA8yyrt6PFKgwKu9usNmpJjporhaOItGlsC1E+xXSoTRskB6XWEGele6b49luQtxMg0YTZpqzzsF5wqiRik1H+FRbW9hZJlqGZvWfnlAhr4LFEla0LP34kjkbxYarx1BbCZvg0hERl4mVdwqVQo4yh+FUvGC5OJjQWRSJnZ9TpTnAPw4CSk7cGqTc1FOtJtkrNeeLc9gkZJBS/1gJHkgivxkxKNUc4DSmy08ehHfT/FSrs10uL11cIk+/zvWrXDYb5+pDRFPVTbNLLmro7am4gBmzONe3fu7lAiGAf7TXu7C8esc110xgaCrl2wS0rc2V2bWCYElYDcoHluZl4OcKkHxckVWL+QC7FWyWcRw6ydJ1aoj8DSJLiaZbpwGM9V33UKChsqxznyZrvALBzod/eohLRatW0tcTN7JKlaAowDT2hQ4CKdW+n9wpavWyBlHZu6tOJCM5zGR6Ys9HHrPOrc0IsveXyZ+fYoDei2fUSg7hiLVFDTJ/3Gy/tyQUtSAxD7UUAgmtzzqWI0P4NbxNrNz3R4CCNnys+h+4/OIBCcQO73IxczJoN8GZc77tuYJphW5Sfkcr63zwK0m5dxrRruTCcBZiBVXTKPG5r8bn4tqz+vAUr2AFc4yGk0qOL+y/VCYQAWD8mYPfEgUl3z/ull7N8DcVQAg6GUFcH/NFByATOA+QQ==,iv:VflumnRSqiHBJbpXngNGtIt032sUPSJK2fCuhHmtQio=,tag:HcYzXwTdYVDBXRFoFz5o+Q==,type:str]\n    key: ENC[AES256_GCM,data:GhA/5rd3PJea2FYy9qH+aLmd/LRchRl232bVs8Mp/U1iCNbEILXabWx5BxKbNv+KjciJPJnmUd5KX6q2fbxedrSU6z28NMQmhJsz8K9WA4vml9OUvpzBH/zUl+ZQjyVOKyR6eqbbUMCplMQiA9uyiaw4uEN3OyesyRZlLyBsr4YHY9sC40JI+m4I2uJ36gPMB0LDIw6jIrqmf9KLqeiCzlH+44emiGhAFgfUfSFiuc0EpyBs,iv:abLvDSPu9cXGHNIoVPKTUK67ogyhkJVhkPSyT+pB6sA=,tag:er6CbXBv2HszjUjGDp4OJQ==,type:str]\nsops:\n  age:\n    - recipient: age19gj66fq5v2veu940ftyj4pkw0w5tgxgddlyqnd00pnjzyndevurqx70g4t\n      enc: |\n        -----BEGIN AGE ENCRYPTED FILE-----\n        YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvc3k4WS9Ed3h4WDFrcmRR\n        d1RNQzdoVzdyMmcwTEF6am9aWGgyUzViS2lBCmJKL0J5dnNBQVRDYW44RHQyUlhC\n        Qnp5empHSDBPV1AwR1Q5clhySitPdkkKLS0tIDRHcm5HdTg2ZGZvVjlCa3U4NkQ0\n        QVVka2owYkdKZnRReWZYT0x1WXNVMUUKdubinR+EZAwxMmxx6qsl7yj8MpzmsEIn\n        1HIw4bTkn7+tOUUUK6A3nkUJnENOlffoJ7hxOxykmqZF20uP5Md9qA==\n        -----END AGE ENCRYPTED FILE-----\n  lastmodified: \"2025-12-22T01:34:33Z\"\n  mac: ENC[AES256_GCM,data:XBMGorZHg+KRAXFLo7sYKE7rWHX5Naq8nQu2xTiK8/2f18WzPD0lhyz/gzk0L4HR3A2qpcsHNQkcADUdWPTbHHlKWsrKKKRqD+xz1QzzYbK46jo88GxlAZE6Bi9vZxmodGvwtudPtpFDKHM9Z/RlVVt2aaPh0dhKDsmiOKy4BiE=,iv:Kpyw1FclLCErE0RaZCtrcWOez6rZX9ORKqd16Ny0/5I=,tag:AwmJJCWwXyNcukx8DAu55Q==,type:str]\n  encrypted_regex: ((?i)(pass|secret($|[^N])|ca|crt|key|token|^data$|^stringData$))\n  mac_only_encrypted: true\n  version: 3.11.0\n"
  },
  {
    "path": "talos/integrations/cert-approver/.gitignore",
    "content": "# Kustomize helmChart transformer creates a charts/ dir that can be ignored\ncharts/\n"
  },
  {
    "path": "talos/integrations/cert-approver/README.md",
    "content": "# Kubelet CSR Approver\n\n## Create Static Kubelet CSR Approver Locally For Talos\n\n```bash\necho \"Removing old local chart cache\"\nrm -rf talos/integrations/cert-approver/charts\necho \"# This manifest was generated by automation. DO NOT EDIT.\" > talos/integrations/cert-approver/cert-approver.yaml\nkustomize build \\\n  --enable-helm \\\n  --load-restrictor=LoadRestrictionsNone \\\n talos/integrations/cert-approver \\\n  >> talos/integrations/cert-approver/cert-approver.yaml\n```\n"
  },
  {
    "path": "talos/integrations/cert-approver/cert-approver.yaml",
    "content": "# This manifest was generated by automation. DO NOT EDIT.\n# Chart: kubelet-csr-approver v1.2.13\n# Source: oci://ghcr.io/postfinance/charts/kubelet-csr-approver\n# Values: kubernetes/apps/base/kube-system/kubelet-csr-approver/app/values.yaml\n---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\n  labels:\n    helm.sh/chart: kubelet-csr-approver-1.2.13\n    app.kubernetes.io/name: kubelet-csr-approver\n    app.kubernetes.io/instance: kubelet-csr-approver\n    app.kubernetes.io/version: \"v1.2.13\"\n    app.kubernetes.io/managed-by: Helm\n  annotations:\n    meta.helm.sh/release-name: kubelet-csr-approver\n    meta.helm.sh/release-namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: kubelet-csr-approver\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  annotations:\n    meta.helm.sh/release-name: kubelet-csr-approver\n    meta.helm.sh/release-namespace: kube-system\nrules:\n  - apiGroups:\n      - coordination.k8s.io\n    resources:\n      - leases\n    verbs:\n      - create\n      - get\n      - update\n  - apiGroups:\n      - \"\"\n    resources:\n      - events\n    verbs:\n      - create\n  - apiGroups:\n      - certificates.k8s.io\n    resources:\n      - certificatesigningrequests\n    verbs:\n      - get\n      - list\n      - watch\n  - apiGroups:\n      - certificates.k8s.io\n    resources:\n      - certificatesigningrequests/approval\n    verbs:\n      - update\n  - apiGroups:\n      - certificates.k8s.io\n    resourceNames:\n      - kubernetes.io/kubelet-serving\n    resources:\n      - signers\n    verbs:\n      - approve\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  annotations:\n    meta.helm.sh/release-name: kubelet-csr-approver\n    meta.helm.sh/release-namespace: kube-system\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: kubelet-csr-approver\nsubjects:\n  - kind: ServiceAccount\n    name: kubelet-csr-approver\n    namespace: kube-system\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\n  labels:\n    helm.sh/chart: kubelet-csr-approver-1.2.13\n    app.kubernetes.io/name: kubelet-csr-approver\n    app.kubernetes.io/instance: kubelet-csr-approver\n    app.kubernetes.io/version: \"v1.2.13\"\n    app.kubernetes.io/managed-by: Helm\n  annotations:\n    meta.helm.sh/release-name: kubelet-csr-approver\n    meta.helm.sh/release-namespace: kube-system\n    prometheus.io/port: \"8080\"\n    prometheus.io/scrape: \"true\"\nspec:\n  type: ClusterIP\n  ports:\n    - port: 8080\n      targetPort: metrics\n      protocol: TCP\n      name: metrics\n  selector:\n    app.kubernetes.io/name: kubelet-csr-approver\n    app.kubernetes.io/instance: kubelet-csr-approver\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\n  labels:\n    helm.sh/chart: kubelet-csr-approver-1.2.13\n    app.kubernetes.io/name: kubelet-csr-approver\n    app.kubernetes.io/instance: kubelet-csr-approver\n    app.kubernetes.io/version: \"v1.2.13\"\n    app.kubernetes.io/managed-by: Helm\n  annotations:\n    meta.helm.sh/release-name: kubelet-csr-approver\n    meta.helm.sh/release-namespace: kube-system\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: kubelet-csr-approver\n      app.kubernetes.io/instance: kubelet-csr-approver\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io/name: kubelet-csr-approver\n        app.kubernetes.io/instance: kubelet-csr-approver\n    spec:\n      serviceAccountName: kubelet-csr-approver\n      securityContext: {}\n      containers:\n        - name: kubelet-csr-approver\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - ALL\n            privileged: false\n            readOnlyRootFilesystem: true\n            runAsGroup: 65532\n            runAsNonRoot: true\n            runAsUser: 65532\n            seccompProfile:\n              type: RuntimeDefault\n          image: \"ghcr.io/postfinance/kubelet-csr-approver:v1.2.13\"\n          imagePullPolicy: IfNotPresent\n          args:\n            - -metrics-bind-address\n            - \":8080\"\n            - -health-probe-bind-address\n            - \":8081\"\n            - -leader-election\n          env:\n            - name: PROVIDER_REGEX\n              value: ^talos-\\d$\n            - name: ALLOWED_DNS_NAMES\n              value: \"1\"\n          ports:\n            - name: metrics\n              containerPort: 8080\n              protocol: TCP\n          livenessProbe:\n            httpGet:\n              path: /healthz\n              port: 8081\n          resources:\n            limits:\n              cpu: 500m\n              memory: 128Mi\n            requests:\n              cpu: 100m\n              memory: 64Mi\n      tolerations:\n        - effect: NoSchedule\n          key: node-role.kubernetes.io/control-plane\n          operator: Equal\n---\napiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: kubelet-csr-approver\n  namespace: kube-system\n  labels:\n    helm.sh/chart: kubelet-csr-approver-1.2.13\n    app.kubernetes.io/name: kubelet-csr-approver\n    app.kubernetes.io/instance: kubelet-csr-approver\n    app.kubernetes.io/version: \"v1.2.13\"\n    app.kubernetes.io/managed-by: Helm\n  annotations:\n    meta.helm.sh/release-name: kubelet-csr-approver\n    meta.helm.sh/release-namespace: kube-system\nspec:\n  endpoints:\n    - interval: 1m\n      path: /metrics\n      port: metrics\n      scheme: http\n      scrapeTimeout: 10s\n  jobLabel: kubelet-csr-approver\n  namespaceSelector:\n    matchNames:\n      - kube-system\n  selector:\n    matchLabels:\n      app.kubernetes.io/instance: kubelet-csr-approver\n      app.kubernetes.io/name: kubelet-csr-approver\n"
  },
  {
    "path": "talos/integrations/cert-approver/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nhelmCharts:\n  - name: kubelet-csr-approver\n    includeCRDs: true\n    skipTests: true\n    releaseName: kubelet-csr-approver\n    namespace: kube-system\n    valuesFile: ../../../kubernetes/apps/base/kube-system/kubelet-csr-approver/app/values.yaml\n    # renovate: registryUrl=oci://ghcr.io/postfinance/charts\n    version: 1.2.13\n    repo: oci://ghcr.io/postfinance/charts\n\n# REQUIRED: Use transformers to avoid creating the labels & annotations on all references rather than only metadata/annotations or metadata/labels respectively\ntransformers:\n  - transformers.yaml\n"
  },
  {
    "path": "talos/integrations/cert-approver/transformers.yaml",
    "content": "---\napiVersion: builtin\nkind: LabelTransformer\nmetadata:\n  name: labels\nlabels:\n  app.kubernetes.io/managed-by: Helm\nfieldSpecs:\n  - path: metadata/labels\n    create: true\n---\napiVersion: builtin\nkind: AnnotationsTransformer\nmetadata:\n  name: annotations\nannotations:\n  meta.helm.sh/release-name: kubelet-csr-approver\n  meta.helm.sh/release-namespace: kube-system\nfieldSpecs:\n  - path: metadata/annotations\n    create: true\n"
  },
  {
    "path": "talos/integrations/cilium/.gitignore",
    "content": "# Kustomize helmChart transformer creates a charts/ dir that can be ignored\ncharts/\n"
  },
  {
    "path": "talos/integrations/cilium/README.md",
    "content": "# Cilium\n\n## Create Static Cilium Locally For Talos\n\n```bash\necho \"Removing old local chart cache\"\nrm -rf talos/integrations/cilium/charts\necho \"# This manifest was generated by automation. DO NOT EDIT.\" > talos/integrations/cilium/cilium.yaml\nkustomize build \\\n  --enable-helm \\\n  --load-restrictor=LoadRestrictionsNone \\\n  talos/integrations/cilium \\\n  >> talos/integrations/cilium/cilium.yaml\n```\n"
  },
  {
    "path": "talos/integrations/cilium/cilium.yaml",
    "content": "# This manifest was generated by automation. DO NOT EDIT.\napiVersion: v1\nkind: Namespace\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-secrets\n---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: cilium\n  namespace: kube-system\n---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: cilium-operator\n  namespace: kube-system\n---\napiVersion: v1\nautomountServiceAccountToken: false\nkind: ServiceAccount\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: hubble-relay\n  namespace: kube-system\n---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: hubble-ui\n  namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-operator-tlsinterception-secrets\n  namespace: cilium-secrets\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - secrets\n  verbs:\n  - create\n  - delete\n  - update\n  - patch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-tlsinterception-secrets\n  namespace: cilium-secrets\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - secrets\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-config-agent\n  namespace: kube-system\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium\nrules:\n- apiGroups:\n  - networking.k8s.io\n  resources:\n  - networkpolicies\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - discovery.k8s.io\n  resources:\n  - endpointslices\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - namespaces\n  - services\n  - pods\n  - endpoints\n  - nodes\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - nodes/status\n  verbs:\n  - patch\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - create\n  - get\n  - update\n  - list\n  - delete\n- apiGroups:\n  - apiextensions.k8s.io\n  resources:\n  - customresourcedefinitions\n  verbs:\n  - list\n  - watch\n  - get\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumloadbalancerippools\n  - ciliumbgppeeringpolicies\n  - ciliumbgpnodeconfigs\n  - ciliumbgpadvertisements\n  - ciliumbgppeerconfigs\n  - ciliumclusterwideenvoyconfigs\n  - ciliumclusterwidenetworkpolicies\n  - ciliumegressgatewaypolicies\n  - ciliumendpoints\n  - ciliumendpointslices\n  - ciliumenvoyconfigs\n  - ciliumidentities\n  - ciliumlocalredirectpolicies\n  - ciliumnetworkpolicies\n  - ciliumnodes\n  - ciliumnodeconfigs\n  - ciliumcidrgroups\n  - ciliuml2announcementpolicies\n  - ciliumpodippools\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumidentities\n  - ciliumendpoints\n  - ciliumnodes\n  verbs:\n  - create\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumidentities\n  verbs:\n  - update\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumendpoints\n  verbs:\n  - delete\n  - get\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumnodes\n  - ciliumnodes/status\n  verbs:\n  - get\n  - update\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumendpoints/status\n  - ciliumendpoints\n  - ciliuml2announcementpolicies/status\n  - ciliumbgpnodeconfigs/status\n  verbs:\n  - patch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-operator\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - pods\n  verbs:\n  - get\n  - list\n  - watch\n  - delete\n- apiGroups:\n  - \"\"\n  resourceNames:\n  - cilium-config\n  resources:\n  - configmaps\n  verbs:\n  - patch\n- apiGroups:\n  - \"\"\n  resources:\n  - nodes\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - nodes\n  - nodes/status\n  verbs:\n  - patch\n- apiGroups:\n  - discovery.k8s.io\n  resources:\n  - endpointslices\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - services/status\n  verbs:\n  - update\n  - patch\n- apiGroups:\n  - \"\"\n  resources:\n  - namespaces\n  - secrets\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - services\n  - endpoints\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumnetworkpolicies\n  - ciliumclusterwidenetworkpolicies\n  verbs:\n  - create\n  - update\n  - deletecollection\n  - patch\n  - get\n  - list\n  - watch\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumnetworkpolicies/status\n  - ciliumclusterwidenetworkpolicies/status\n  verbs:\n  - patch\n  - update\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumendpoints\n  - ciliumidentities\n  verbs:\n  - delete\n  - list\n  - watch\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumidentities\n  verbs:\n  - update\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumnodes\n  verbs:\n  - create\n  - update\n  - get\n  - list\n  - watch\n  - delete\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumnodes/status\n  verbs:\n  - update\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumendpointslices\n  - ciliumenvoyconfigs\n  - ciliumbgppeerconfigs\n  - ciliumbgpadvertisements\n  - ciliumbgpnodeconfigs\n  verbs:\n  - create\n  - update\n  - get\n  - list\n  - watch\n  - delete\n  - patch\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumbgpclusterconfigs/status\n  - ciliumbgppeerconfigs/status\n  verbs:\n  - update\n- apiGroups:\n  - apiextensions.k8s.io\n  resources:\n  - customresourcedefinitions\n  verbs:\n  - create\n  - get\n  - list\n  - watch\n- apiGroups:\n  - apiextensions.k8s.io\n  resourceNames:\n  - ciliumloadbalancerippools.cilium.io\n  - ciliumbgppeeringpolicies.cilium.io\n  - ciliumbgpclusterconfigs.cilium.io\n  - ciliumbgppeerconfigs.cilium.io\n  - ciliumbgpadvertisements.cilium.io\n  - ciliumbgpnodeconfigs.cilium.io\n  - ciliumbgpnodeconfigoverrides.cilium.io\n  - ciliumclusterwideenvoyconfigs.cilium.io\n  - ciliumclusterwidenetworkpolicies.cilium.io\n  - ciliumegressgatewaypolicies.cilium.io\n  - ciliumendpoints.cilium.io\n  - ciliumendpointslices.cilium.io\n  - ciliumenvoyconfigs.cilium.io\n  - ciliumidentities.cilium.io\n  - ciliumlocalredirectpolicies.cilium.io\n  - ciliumnetworkpolicies.cilium.io\n  - ciliumnodes.cilium.io\n  - ciliumnodeconfigs.cilium.io\n  - ciliumcidrgroups.cilium.io\n  - ciliuml2announcementpolicies.cilium.io\n  - ciliumpodippools.cilium.io\n  - ciliumgatewayclassconfigs.cilium.io\n  resources:\n  - customresourcedefinitions\n  verbs:\n  - update\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumloadbalancerippools\n  - ciliumpodippools\n  - ciliumbgppeeringpolicies\n  - ciliumbgpclusterconfigs\n  - ciliumbgpnodeconfigoverrides\n  - ciliumbgppeerconfigs\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumpodippools\n  verbs:\n  - create\n- apiGroups:\n  - cilium.io\n  resources:\n  - ciliumloadbalancerippools/status\n  verbs:\n  - patch\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - create\n  - get\n  - update\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: hubble-ui\nrules:\n- apiGroups:\n  - networking.k8s.io\n  resources:\n  - networkpolicies\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - componentstatuses\n  - endpoints\n  - namespaces\n  - nodes\n  - pods\n  - services\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - apiextensions.k8s.io\n  resources:\n  - customresourcedefinitions\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - cilium.io\n  resources:\n  - '*'\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-operator-tlsinterception-secrets\n  namespace: cilium-secrets\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: cilium-operator-tlsinterception-secrets\nsubjects:\n- kind: ServiceAccount\n  name: cilium-operator\n  namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-tlsinterception-secrets\n  namespace: cilium-secrets\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: cilium-tlsinterception-secrets\nsubjects:\n- kind: ServiceAccount\n  name: cilium\n  namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-config-agent\n  namespace: kube-system\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: cilium-config-agent\nsubjects:\n- kind: ServiceAccount\n  name: cilium\n  namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: cilium\nsubjects:\n- kind: ServiceAccount\n  name: cilium\n  namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: cilium-operator\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: cilium-operator\nsubjects:\n- kind: ServiceAccount\n  name: cilium-operator\n  namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/part-of: cilium\n  name: hubble-ui\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: hubble-ui\nsubjects:\n- kind: ServiceAccount\n  name: hubble-ui\n  namespace: kube-system\n---\napiVersion: v1\ndata:\n  agent-not-ready-taint-key: node.cilium.io/agent-not-ready\n  annotate-k8s-node: \"true\"\n  auto-direct-node-routes: \"true\"\n  bpf-distributed-lru: \"false\"\n  bpf-events-drop-enabled: \"true\"\n  bpf-events-policy-verdict-enabled: \"true\"\n  bpf-events-trace-enabled: \"true\"\n  bpf-lb-acceleration: disabled\n  bpf-lb-algorithm: maglev\n  bpf-lb-algorithm-annotation: \"false\"\n  bpf-lb-external-clusterip: \"false\"\n  bpf-lb-map-max: \"65536\"\n  bpf-lb-mode: hybrid\n  bpf-lb-mode-annotation: \"false\"\n  bpf-lb-sock: \"false\"\n  bpf-lb-source-range-all-types: \"false\"\n  bpf-map-dynamic-size-ratio: \"0.0025\"\n  bpf-policy-map-max: \"16384\"\n  bpf-policy-stats-map-max: \"65536\"\n  bpf-root: /sys/fs/bpf\n  cgroup-root: /sys/fs/cgroup\n  cilium-endpoint-gc-interval: 5m0s\n  cluster-id: \"0\"\n  cluster-name: default\n  clustermesh-enable-endpoint-sync: \"false\"\n  clustermesh-enable-mcs-api: \"false\"\n  cni-exclusive: \"false\"\n  cni-log-file: /var/run/cilium/cilium-cni.log\n  controller-group-metrics: write-cni-file sync-host-ips sync-lb-maps-with-k8s-services\n  custom-cni-conf: \"false\"\n  datapath-mode: netkit\n  debug: \"false\"\n  debug-verbose: \"\"\n  default-lb-service-ipam: lbipam\n  direct-routing-skip-unreachable: \"false\"\n  dnsproxy-enable-transparent-mode: \"true\"\n  dnsproxy-socket-linger-timeout: \"10\"\n  egress-gateway-reconciliation-trigger-interval: 1s\n  enable-auto-protect-node-port-range: \"true\"\n  enable-bandwidth-manager: \"true\"\n  enable-bbr: \"true\"\n  enable-bbr-hostns-only: \"false\"\n  enable-bpf-clock-probe: \"false\"\n  enable-bpf-masquerade: \"true\"\n  enable-bpf-tproxy: \"true\"\n  enable-endpoint-health-checking: \"true\"\n  enable-endpoint-lockdown-on-policy-overflow: \"false\"\n  enable-endpoint-routes: \"true\"\n  enable-health-check-loadbalancer-ip: \"false\"\n  enable-health-check-nodeport: \"true\"\n  enable-health-checking: \"true\"\n  enable-hubble: \"true\"\n  enable-internal-traffic-policy: \"true\"\n  enable-ipv4: \"true\"\n  enable-ipv4-big-tcp: \"false\"\n  enable-ipv4-masquerade: \"true\"\n  enable-ipv6: \"false\"\n  enable-ipv6-big-tcp: \"false\"\n  enable-ipv6-masquerade: \"true\"\n  enable-k8s-networkpolicy: \"true\"\n  enable-l2-announcements: \"true\"\n  enable-l2-neigh-discovery: \"false\"\n  enable-l7-proxy: \"true\"\n  enable-lb-ipam: \"true\"\n  enable-local-redirect-policy: \"true\"\n  enable-masquerade-to-route-source: \"false\"\n  enable-metrics: \"true\"\n  enable-node-selector-labels: \"false\"\n  enable-non-default-deny-policies: \"true\"\n  enable-pmtu-discovery: \"true\"\n  enable-policy: default\n  enable-policy-secrets-sync: \"true\"\n  enable-sctp: \"false\"\n  enable-source-ip-verification: \"true\"\n  enable-svc-source-range-check: \"true\"\n  enable-tcx: \"true\"\n  enable-vtep: \"false\"\n  enable-well-known-identities: \"false\"\n  enable-xt-socket-fallback: \"true\"\n  envoy-access-log-buffer-size: \"4096\"\n  envoy-base-id: \"0\"\n  envoy-keep-cap-netbindservice: \"false\"\n  external-envoy-proxy: \"false\"\n  health-check-icmp-failure-threshold: \"3\"\n  http-retry-count: \"3\"\n  hubble-disable-tls: \"false\"\n  hubble-listen-address: :4244\n  hubble-network-policy-correlation-enabled: \"true\"\n  hubble-socket-path: /var/run/cilium/hubble.sock\n  hubble-tls-cert-file: /var/lib/cilium/tls/hubble/server.crt\n  hubble-tls-client-ca-files: /var/lib/cilium/tls/hubble/client-ca.crt\n  hubble-tls-key-file: /var/lib/cilium/tls/hubble/server.key\n  identity-allocation-mode: crd\n  identity-gc-interval: 15m0s\n  identity-heartbeat-timeout: 30m0s\n  identity-management-mode: agent\n  install-no-conntrack-iptables-rules: \"false\"\n  ipam: kubernetes\n  ipam-cilium-node-update-rate: 15s\n  iptables-random-fully: \"false\"\n  ipv4-native-routing-cidr: 10.244.0.0/16\n  k8s-require-ipv4-pod-cidr: \"false\"\n  k8s-require-ipv6-pod-cidr: \"false\"\n  kube-proxy-replacement: \"true\"\n  kube-proxy-replacement-healthz-bind-address: 0.0.0.0:10256\n  max-connected-clusters: \"255\"\n  mesh-auth-enabled: \"true\"\n  mesh-auth-gc-interval: 5m0s\n  mesh-auth-queue-size: \"1024\"\n  mesh-auth-rotated-identities-queue-size: \"1024\"\n  metrics-sampling-interval: 5m\n  monitor-aggregation: medium\n  monitor-aggregation-flags: all\n  monitor-aggregation-interval: 5s\n  nat-map-stats-entries: \"32\"\n  nat-map-stats-interval: 30s\n  node-port-bind-protection: \"true\"\n  nodeport-addresses: \"\"\n  nodes-gc-interval: 5m0s\n  operator-api-serve-addr: 127.0.0.1:9234\n  operator-prometheus-serve-addr: :9963\n  policy-cidr-match-mode: \"\"\n  policy-default-local-cluster: \"false\"\n  policy-secrets-namespace: cilium-secrets\n  policy-secrets-only-from-secrets-namespace: \"true\"\n  preallocate-bpf-maps: \"true\"\n  procfs: /host/proc\n  prometheus-serve-addr: :9962\n  proxy-connect-timeout: \"2\"\n  proxy-idle-timeout-seconds: \"60\"\n  proxy-initial-fetch-timeout: \"30\"\n  proxy-max-concurrent-retries: \"128\"\n  proxy-max-connection-duration-seconds: \"0\"\n  proxy-max-requests-per-connection: \"0\"\n  proxy-prometheus-port: \"9964\"\n  proxy-xff-num-trusted-hops-egress: \"0\"\n  proxy-xff-num-trusted-hops-ingress: \"0\"\n  remove-cilium-node-taints: \"true\"\n  routing-mode: native\n  service-no-backend-response: reject\n  set-cilium-is-up-condition: \"true\"\n  set-cilium-node-taints: \"true\"\n  synchronize-k8s-nodes: \"true\"\n  tofqdns-dns-reject-response-code: refused\n  tofqdns-enable-dns-compression: \"true\"\n  tofqdns-endpoint-max-ip-per-hostname: \"1000\"\n  tofqdns-idle-connection-grace-period: 0s\n  tofqdns-max-deferred-connection-deletes: \"10000\"\n  tofqdns-preallocate-identities: \"true\"\n  tofqdns-proxy-response-max-delay: 100ms\n  tunnel-protocol: vxlan\n  tunnel-source-port-range: 0-0\n  unmanaged-pod-watcher-interval: \"15\"\n  vtep-cidr: \"\"\n  vtep-endpoint: \"\"\n  vtep-mac: \"\"\n  vtep-mask: \"\"\n  write-cni-conf-when-ready: /host/etc/cni/net.d/05-cilium.conflist\nkind: ConfigMap\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: cilium-config\n  namespace: kube-system\n---\napiVersion: v1\ndata:\n  cilium-dashboard.json: |-\n    {\n      \"annotations\": {\n        \"list\": [\n          {\n            \"builtIn\": 1,\n            \"datasource\": {\n              \"type\": \"datasource\",\n              \"uid\": \"grafana\"\n            },\n            \"enable\": true,\n            \"hide\": true,\n            \"iconColor\": \"rgba(0, 211, 255, 1)\",\n            \"name\": \"Annotations & Alerts\",\n            \"type\": \"dashboard\"\n          }\n        ]\n      },\n      \"description\": \"Dashboard for Cilium (https://cilium.io/) metrics\",\n      \"editable\": true,\n      \"fiscalYearStartMonth\": 0,\n      \"graphTooltip\": 1,\n      \"id\": 1,\n      \"links\": [],\n      \"panels\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"error\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"warning\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#c15c17\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 0\n          },\n          \"id\": 76,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"sum(rate(cilium_errors_warnings_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, level) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{level}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Errors & Warnings\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"percent\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#cffaff\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 0\n          },\n          \"id\": 96,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(irate(cilium_process_cpu_seconds_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod) * 100\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(irate(cilium_process_cpu_seconds_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod) * 100\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(irate(cilium_process_cpu_seconds_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod) * 100\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            }\n          ],\n          \"title\": \"CPU Usage per node\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"collapsed\": false,\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 5\n          },\n          \"id\": 161,\n          \"panels\": [],\n          \"title\": \"Generic\",\n          \"type\": \"row\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"bytes\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"AVG_virtual_memory_bytes\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#508642\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Average Virtual Memory\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#f9d9f9\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"MAX_virtual_memory_bytes\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e5ac0e\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Max Virtual Memory\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#584477\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Max Virtual Memory\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"Min Virtual Memory\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Min Virtual Memory\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 8,\n            \"x\": 0,\n            \"y\": 6\n          },\n          \"id\": 26,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_process_virtual_memory_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Min Virtual Memory\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_process_virtual_memory_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Average Virtual Memory\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_process_virtual_memory_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Max Virtual Memory\",\n              \"refId\": \"C\"\n            }\n          ],\n          \"title\": \"Virtual Memory Bytes\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"bytes\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"MAX_resident_memory_bytes_max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e5ac0e\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 8,\n            \"x\": 8,\n            \"y\": 6\n          },\n          \"id\": 24,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_process_resident_memory_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"AVG_resident_memory_bytes\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_process_resident_memory_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"MAX_resident_memory_bytes_max\",\n              \"refId\": \"D\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_process_resident_memory_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"MIN_resident_memory_bytes_min\",\n              \"refId\": \"E\"\n            }\n          ],\n          \"title\": \"Resident memory status\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"all nodes\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e5a8e2\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 8,\n            \"x\": 16,\n            \"y\": 6\n          },\n          \"id\": 98,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_process_open_fds{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"all nodes\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_process_open_fds{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min/node\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_process_open_fds{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg/node\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_process_open_fds{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max/node\",\n              \"refId\": \"D\"\n            }\n          ],\n          \"title\": \"Open file descriptors\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"description\": \"BPF memory usage in the entire system including components not managed by Cilium.\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"bytes\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"MAX_resident_memory_bytes_max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e5ac0e\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 11\n          },\n          \"id\": 178,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_bpf_maps_virtual_memory_max_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"} + cilium_bpf_progs_virtual_memory_max_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"hide\": false,\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"AVG_bpf_memory_bytes_avg\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_bpf_maps_virtual_memory_max_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"} + cilium_bpf_progs_virtual_memory_max_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"hide\": false,\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"MAX_bpf_memory_bytes_max\",\n              \"refId\": \"D\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_bpf_maps_virtual_memory_max_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"} + cilium_bpf_progs_virtual_memory_max_bytes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"})\",\n              \"format\": \"time_series\",\n              \"hide\": false,\n              \"instant\": false,\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"MIN_bpf_memory_bytes_min\",\n              \"refId\": \"E\"\n            }\n          ],\n          \"title\": \"System-wide BPF memory usage\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"description\": \"Fill percentage of BPF maps, tagged by map name\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"max\": 1,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"percentunit\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 11\n          },\n          \"id\": 194,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"cilium_bpf_map_pressure{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}\",\n              \"interval\": \"\",\n              \"legendFormat\": \"\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"BPF map pressure\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"collapsed\": false,\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 17\n          },\n          \"id\": 155,\n          \"panels\": [],\n          \"title\": \"API\",\n          \"type\": \"row\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 18\n          },\n          \"id\": 152,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_agent_api_process_time_seconds_sum{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])/rate(cilium_agent_api_process_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{path}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"API call latency (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 18\n          },\n          \"id\": 153,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(rate(cilium_agent_api_process_time_seconds_sum{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])/rate(cilium_agent_api_process_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{path}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"API call latency (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 24\n          },\n          \"id\": 156,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_agent_api_process_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{path}} \",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"# API calls (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 24\n          },\n          \"id\": 157,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(rate(cilium_agent_api_process_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{path}} \",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"# API calls (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 30\n          },\n          \"id\": 159,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_agent_api_process_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path, return_code)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{return_code}} ({{method}} {{path}} )\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"API return codes (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 30\n          },\n          \"id\": 158,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_agent_api_process_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path, return_code)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{return_code}} ({{method}} {{path}} )\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"API return codes (sum all nodes)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"collapsed\": false,\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 36\n          },\n          \"id\": 72,\n          \"panels\": [],\n          \"title\": \"Cilium\",\n          \"type\": \"row\"\n        },\n        {\n          \"fieldConfig\": {\n            \"defaults\": {},\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 37\n          },\n          \"id\": 144,\n          \"options\": {\n            \"code\": {\n              \"language\": \"plaintext\",\n              \"showLineNumbers\": false,\n              \"showMiniMap\": false\n            },\n            \"content\": \"\",\n            \"mode\": \"markdown\"\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"title\": \"BPF\",\n          \"type\": \"text\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 38\n          },\n          \"id\": 146,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"avg(rate(cilium_bpf_syscall_duration_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, operation)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{operation}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"# system calls (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"decimals\": 0,\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 38\n          },\n          \"id\": 145,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(rate(cilium_bpf_syscall_duration_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, operation)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{operation}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"# system calls (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 46\n          },\n          \"id\": 140,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_bpf_syscall_duration_seconds_sum{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])/ rate(cilium_bpf_syscall_duration_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, operation)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{operation}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"system call latency (avg node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 46\n          },\n          \"id\": 148,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(rate(cilium_bpf_syscall_duration_seconds_sum{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])/ rate(cilium_bpf_syscall_duration_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, operation)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{operation}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"system call latency (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 8,\n            \"x\": 0,\n            \"y\": 52\n          },\n          \"id\": 142,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"topk(5, avg(rate(cilium_bpf_map_ops_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[5m])) by (pod, map_name, operation))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{map_name}} {{operation}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"map ops (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 8,\n            \"x\": 8,\n            \"y\": 52\n          },\n          \"id\": 147,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"topk(5, max(rate(cilium_bpf_map_ops_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[5m])) by (pod, map_name, operation))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{map_name}} {{operation}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"map ops (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 8,\n            \"x\": 16,\n            \"y\": 52\n          },\n          \"id\": 143,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_bpf_map_ops_total{k8s_app=\\\"cilium\\\",outcome=\\\"fail\\\", pod=~\\\"$pod\\\"}[5m])) by (pod, map_name, operation)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{map_name}} {{operation}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"map ops (sum failures)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"fieldConfig\": {\n            \"defaults\": {},\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 58\n          },\n          \"id\": 182,\n          \"options\": {\n            \"code\": {\n              \"language\": \"plaintext\",\n              \"showLineNumbers\": false,\n              \"showMiniMap\": false\n            },\n            \"content\": \"\",\n            \"mode\": \"markdown\"\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"title\": \"kvstore\",\n          \"type\": \"text\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"decimals\": 0,\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 59\n          },\n          \"id\": 184,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(kvstore_operations_total{pod=~\\\"$pod\\\"}[1m])) by (pod, scope, action)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{scope}} {{action}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"# operations (sum all nodes)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"decimals\": 0,\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 59\n          },\n          \"id\": 186,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(rate(kvstore_operations_total{pod=~\\\"$pod\\\"}[1m])) by (pod, scope, action)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{scope}} {{action}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"# operations (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 64\n          },\n          \"id\": 188,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"topk(5, avg(rate(cilium_kvstore_operations_duration_seconds_sum{pod=~\\\"$pod\\\"}[1m])) by (pod, action, scope) / avg(rate(cilium_kvstore_operations_duration_seconds_count{pod=~\\\"$pod\\\"}[1m])) by (pod, action, scope))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} {{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"latency (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 64\n          },\n          \"id\": 190,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"topk(5, max(rate(cilium_kvstore_operations_duration_seconds_sum{pod=~\\\"$pod\\\"}[1m])) by (pod, action, scope) / avg(rate(cilium_kvstore_operations_duration_seconds_count{pod=~\\\"$pod\\\"}[1m])) by (pod, action, scope))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} {{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"latency (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 69\n          },\n          \"id\": 192,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kvstore_events_queue_seconds_count{pod=~\\\"$pod\\\"}[1m])) by (pod, scope, action)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} {{scope}}\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Events received (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"fieldConfig\": {\n            \"defaults\": {},\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 75\n          },\n          \"id\": 47,\n          \"options\": {\n            \"code\": {\n              \"language\": \"plaintext\",\n              \"showLineNumbers\": false,\n              \"showMiniMap\": false\n            },\n            \"content\": \"\",\n            \"mode\": \"markdown\"\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"title\": \"Cilium network information\",\n          \"type\": \"text\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"pps\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 76\n          },\n          \"id\": 81,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_forward_count_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, direction)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{direction}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Forwarded Packets\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"bps\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 76\n          },\n          \"id\": 111,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_forward_bytes_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, direction) * 8\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{direction}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Forwarded Traffic\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#0a50a1\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#f9d9f9\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#806eb7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive CT entries ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#badff4\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted CT entries ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 denied request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 forwarded request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#7eb26d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0f9d7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#6ed0e0\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#447ebc\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 82\n          },\n          \"id\": 56,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv4\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv4\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv4\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv4\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted\",\n              \"refId\": \"D\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv4\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted max\",\n              \"refId\": \"E\"\n            }\n          ],\n          \"title\": \"IPv4 Conntrack TCP\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#0a50a1\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#f9d9f9\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#806eb7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive CT entries ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#badff4\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted CT entries ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 denied request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 forwarded request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#7eb26d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0f9d7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#6ed0e0\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#447ebc\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 82\n          },\n          \"id\": 128,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv6\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv6\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv6\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv6\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted\",\n              \"refId\": \"D\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv6\\\", protocol=\\\"TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted max\",\n              \"refId\": \"E\"\n            }\n          ],\n          \"title\": \"IPv6 Conntrack TCP\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#0a50a1\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#f9d9f9\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#806eb7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive CT entries ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#badff4\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted CT entries ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 denied request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 forwarded request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#7eb26d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0f9d7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#6ed0e0\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#447ebc\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 88\n          },\n          \"id\": 129,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv4\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv4\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv4\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv4\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted\",\n              \"refId\": \"D\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv4\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted max\",\n              \"refId\": \"E\"\n            }\n          ],\n          \"title\": \"IPv4 Conntrack Non-TCP\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#0a50a1\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#f9d9f9\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#806eb7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive  ipv6 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Alive CT entries ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#badff4\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted CT entries ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv4 non-TCP\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Deleted ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 denied request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 forwarded request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#7eb26d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0f9d7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#6ed0e0\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"deleted max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#447ebc\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#629e51\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 88\n          },\n          \"id\": 130,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv6\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv6\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"alive\\\", family=\\\"ipv6\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv6\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted\",\n              \"refId\": \"D\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_datapath_conntrack_gc_entries{k8s_app=\\\"cilium\\\", status=\\\"deleted\\\", family=\\\"ipv6\\\", protocol=\\\"non-TCP\\\", pod=~\\\"$pod\\\"}) by (family,status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"deleted max\",\n              \"refId\": \"E\"\n            }\n          ],\n          \"title\": \"IPv6 Conntrack Non-TCP\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 0,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#5195ce\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#6d1f62\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 94\n          },\n          \"id\": 87,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"lastNotNull\",\n                \"max\",\n                \"min\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_ip_addresses{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod, family)\\n\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{family}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Allocated Addresses\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"dump_interrupts conntrack ipv4\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#ea6460\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"dump_interrupts conntrack ipv6\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#58140c\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 94\n          },\n          \"id\": 79,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_datapath_conntrack_dump_resets_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod, area, family, name)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{name}} {{area}} {{family}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Datapath Conntrack Dump Resets\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 99\n          },\n          \"id\": 106,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_services_events_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Service Updates\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 99\n          },\n          \"id\": 89,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_unreachable_nodes{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"unreachable nodes\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_unreachable_health_endpoints{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"unreachable health endpoints\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Connectivity Health\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 104\n          },\n          \"id\": 39,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_drop_count_total{direction=\\\"EGRESS\\\", k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (reason)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{reason}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Dropped Egress Packets\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#cca300\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"rgb(167, 150, 111)\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"Min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"add k8s\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"short\"\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"delete k8s\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"short\"\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"update k8s\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"short\"\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"add local-node\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"short\"\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 104\n          },\n          \"id\": 93,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_nodes_all_events_received_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, event_type, source) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{eventType}} {{source}}\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Node Events\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"bps\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 109\n          },\n          \"id\": 113,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_drop_bytes_total{direction=\\\"EGRESS\\\", k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (reason) * 8\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{reason}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Dropped Egress Traffic\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Average Nodes\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#eab839\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Max Nodes\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#c15c17\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Max Nodes\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"Min Nodes\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Min Nodes\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 109\n          },\n          \"id\": 91,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_nodes_all_num{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Average Nodes\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_nodes_all_num{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Min Nodes\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_nodes_all_num{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Max Nodes\",\n              \"refId\": \"C\"\n            }\n          ],\n          \"title\": \"Nodes\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"fieldConfig\": {\n            \"defaults\": {},\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 114\n          },\n          \"id\": 28,\n          \"options\": {\n            \"code\": {\n              \"language\": \"plaintext\",\n              \"showLineNumbers\": false,\n              \"showMiniMap\": false\n            },\n            \"content\": \"\",\n            \"mode\": \"markdown\"\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"title\": \"Policy\",\n          \"type\": \"text\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"reqps\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 denied request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#ea6460\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"L7 forwarded request\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#7eb26d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"denied\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 115\n          },\n          \"id\": 53,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"sum by(rule, proxy_type) (rate(cilium_policy_l7_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m]))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{proxy_type}} - {{rule}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"L7 forwarded request\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"description\": \"99th percentile of DNS proxy request processing latency, by span\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 34,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineStyle\": {\n                  \"fill\": \"solid\"\n                },\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"auto\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 115\n          },\n          \"id\": 123,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"histogram_quantile(0.99, sum by(scope, le) (rate(cilium_proxy_upstream_reply_seconds_bucket{protocol_l7=\\\"dns\\\", k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\", scope!=\\\"totalTime\\\"}[5m]))) \\n\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{scope}}\",\n              \"range\": true,\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"DNS proxy request latency\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              },\n              \"unit\": \"pps\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 120\n          },\n          \"id\": 114,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_drop_count_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\", reason=\\\"Policy denied\\\"}[1m])) by (direction)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{direction}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Policy Denies: L3/L4\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 120\n          },\n          \"id\": 37,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_policy_l7_total{rule=\\\"denied\\\", k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (proxy_type)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{reason}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Policy Denies: L7\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"description\": \"End-to-end duration to apply incremental identity updates to the policy control and data planes.\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#64b0c8\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"count\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#9ac48a\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#5195ce\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#6ed0e0\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg count\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"opm\"\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max count\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"opm\"\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 125\n          },\n          \"id\": 104,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"histogram_quantile(0.99, sum by(le) (rate(cilium_policy_incremental_update_duration_bucket{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[5m])))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"99%\",\n              \"range\": true,\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"histogram_quantile(0.5, sum by(le) (rate(cilium_policy_incremental_update_duration_bucket{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[5m])))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"50%\",\n              \"range\": true,\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Policy Identity Update Latency\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"description\": \"The time taken for new or updated network policy to be applied to all affected endpoints\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"average duration\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#d683ce\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"folds\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max duration\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max trigger\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#967302\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min duration\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#584477\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min trigger\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#fceaca\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min trigger\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min trigger\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"folds\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"short\"\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 125\n          },\n          \"id\": 102,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"histogram_quantile(0.99, sum by(le) (rate(cilium_policy_implementation_delay_bucket{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[5m])))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"99%\",\n              \"range\": true,\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"histogram_quantile(0.5, sum by(le) (rate(cilium_policy_implementation_delay_bucket{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[5m])))  \",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"50%\",\n              \"range\": true,\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Policy Apply Latency\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"both\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#7eb26d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"egress\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e5ac0e\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"ingress\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0752d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"none\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 6,\n            \"x\": 0,\n            \"y\": 130\n          },\n          \"id\": 33,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"lastNotNull\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"single\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_policy_endpoint_enforcement_status{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (enforcement)\",\n              \"format\": \"time_series\",\n              \"hide\": false,\n              \"instant\": true,\n              \"interval\": \"1s\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{enforcement}}\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Endpoints policy enforcement status\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#b7dbab\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"rgba(89, 132, 76, 0.54)\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#2f575e\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 6,\n            \"x\": 6,\n            \"y\": 130\n          },\n          \"id\": 100,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_proxy_redirects{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_proxy_redirects{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_proxy_redirects{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            }\n          ],\n          \"title\": \"Proxy Redirects\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"description\": \"Endpoint policy calculation time by stage. Shows the 99th-percentile.\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#f9d9f9\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#806eb7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#806eb7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 130\n          },\n          \"id\": 117,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"histogram_quantile(0.99, sum by(scope, le) (rate(cilium_endpoint_regeneration_time_stats_seconds_bucket{scope=~\\\"proxyConfiguration|endpointPolicyCalculation|selectorPolicyCalculation|proxyPolicyCalculation\\\",k8s_app=\\\"cilium\\\",status=\\\"success\\\",pod=~\\\"$pod\\\"}[5m])))\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"__auto\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Policy Calculation Time\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 35,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#f2c96d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"policy change errors\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"policy errors\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"max\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.fillBelowTo\",\n                    \"value\": \"min\"\n                  },\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.lineWidth\",\n                    \"value\": 0\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 135\n          },\n          \"id\": 85,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"lastNotNull\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"min(cilium_policy{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by(pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(cilium_policy{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by(pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(cilium_policy{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by(pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_policy_change_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\", outcome=\\\"fail\\\"}) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"policy change errors\",\n              \"refId\": \"D\"\n            }\n          ],\n          \"title\": \"Policies Per Node\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"fieldConfig\": {\n            \"defaults\": {},\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 140\n          },\n          \"id\": 73,\n          \"options\": {\n            \"code\": {\n              \"language\": \"plaintext\",\n              \"showLineNumbers\": false,\n              \"showMiniMap\": false\n            },\n            \"content\": \"\",\n            \"mode\": \"markdown\"\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"title\": \"Endpoints\",\n          \"type\": \"text\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 9,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 141\n          },\n          \"id\": 55,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(histogram_quantile(0.90, rate(cilium_endpoint_regeneration_time_stats_seconds_bucket{k8s_app=\\\"cilium\\\", scope!=\\\"total\\\", pod=~\\\"$pod\\\"}[5m]))) by (scope)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Endpoint regeneration time (90th percentile)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 9,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 141\n          },\n          \"id\": 115,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(histogram_quantile(0.99, rate(cilium_endpoint_regeneration_time_stats_seconds_bucket{k8s_app=\\\"cilium\\\", scope!=\\\"total\\\", pod=~\\\"$pod\\\"}[5m]))) by (scope)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Endpoint regeneration time (99th percentile)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 2,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"fail\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"fail/min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"success\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#447ebc\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"success/min\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#3f6833\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 150\n          },\n          \"id\": 49,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"single\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_endpoint_regenerations_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[30s])) by(outcome)\",\n              \"format\": \"time_series\",\n              \"instant\": false,\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{outcome}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Endpoint regenerations\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 2,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": true,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"disconnecting\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#614d93\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"ready\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"rgba(81, 220, 95, 0.52)\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"waiting-to-regenerate\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#0a50a1\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 150\n          },\n          \"id\": 51,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"lastNotNull\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"single\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_endpoint_state{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by (endpoint_state)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{endpoint_state}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Cilium endpoint state\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"fieldConfig\": {\n            \"defaults\": {},\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 155\n          },\n          \"id\": 74,\n          \"options\": {\n            \"code\": {\n              \"language\": \"plaintext\",\n              \"showLineNumbers\": false,\n              \"showMiniMap\": false\n            },\n            \"content\": \"\",\n            \"mode\": \"markdown\"\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"title\": \"Controllers\",\n          \"type\": \"text\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 30,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Failed\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#bf1b00\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Failing\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Runs\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#5195ce\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 156\n          },\n          \"id\": 70,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_controllers_runs_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Runs\",\n              \"refId\": \"A\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(cilium_controllers_failing{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}) by(pod)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"Failed\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Controllers\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"duration failure\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"duration success\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#508642\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"failure\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"runs failure\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#890f02\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"runs success\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#7eb26d\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"success\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#508642\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 156\n          },\n          \"id\": 68,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\",\n                \"min\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_controllers_runs_duration_seconds_sum{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, status) / sum(rate(cilium_controllers_runs_duration_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{status}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Controller Durations\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"fieldConfig\": {\n            \"defaults\": {},\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 161\n          },\n          \"id\": 60,\n          \"options\": {\n            \"code\": {\n              \"language\": \"plaintext\",\n              \"showLineNumbers\": false,\n              \"showMiniMap\": false\n            },\n            \"content\": \"\",\n            \"mode\": \"markdown\"\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"title\": \"Kubernetes integration\",\n          \"type\": \"text\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 162\n          },\n          \"id\": 163,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_k8s_client_api_latency_time_seconds_sum{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])/rate(cilium_k8s_client_api_latency_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{path}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"apiserver latency (average node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"s\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 162\n          },\n          \"id\": 165,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"max(rate(cilium_k8s_client_api_latency_time_seconds_sum{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])/rate(cilium_k8s_client_api_latency_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{path}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"apiserver latency (max node)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 169\n          },\n          \"id\": 168,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_k8s_client_api_latency_time_seconds_count{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, path)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{path}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"apiserver #calls (sum all nodes)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 169\n          },\n          \"id\": 166,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_k8s_client_api_calls_total{k8s_app=\\\"cilium\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, method, return_code)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{method}} {{return_code}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"apiserver calls (sum all nodes)\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 177\n          },\n          \"id\": 172,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_kubernetes_events_received_total{k8s_app=\\\"cilium\\\", equal=\\\"true\\\", valid=\\\"true\\\", pod=~\\\"$pod\\\"}[5m])) by (pod, scope, action)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} {{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Valid, Unnecessary K8s Events Received\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"short\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 177\n          },\n          \"id\": 174,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_kubernetes_events_received_total{k8s_app=\\\"cilium\\\", equal=\\\"true\\\", valid=\\\"false\\\", pod=~\\\"$pod\\\"}[5m])) by (pod, scope, action)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} {{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Invalid, Unnecessary K8s Events Received\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 183\n          },\n          \"id\": 175,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_kubernetes_events_received_total{k8s_app=\\\"cilium\\\", equal=\\\"false\\\", valid=\\\"true\\\", pod=~\\\"$pod\\\"}[5m])) by (pod, scope, action, valid)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} {{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Valid, Necessary K8s Events Received\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"ops\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsZero\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byValue\",\n                  \"options\": {\n                    \"op\": \"gte\",\n                    \"reducer\": \"allIsNull\",\n                    \"value\": 0\n                  }\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"custom.hideFrom\",\n                    \"value\": {\n                      \"legend\": true,\n                      \"tooltip\": true,\n                      \"viz\": false\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 183\n          },\n          \"id\": 173,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\"\n              ],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"sum(rate(cilium_kubernetes_events_received_total{k8s_app=\\\"cilium\\\", equal=\\\"false\\\", valid=\\\"false\\\", pod=~\\\"$pod\\\"}[5m])) by (pod, scope, action)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} {{scope}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Invalid, Necessary K8s Events Received\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 191\n          },\n          \"id\": 108,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kubernetes_events_total{k8s_app=\\\"cilium\\\", scope=\\\"CiliumNetworkPolicy\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} avg\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"CiliumNetworkPolicy Events\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"create avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#70dbed\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"delete avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e24d42\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"update avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0f9d7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 191\n          },\n          \"id\": 119,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kubernetes_events_total{k8s_app=\\\"cilium\\\", scope=\\\"NetworkPolicy\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} avg\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"NetworkPolicy Events\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"create avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#70dbed\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"delete avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e24d42\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"update avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0f9d7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 198\n          },\n          \"id\": 109,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kubernetes_events_total{k8s_app=\\\"cilium\\\", scope=\\\"Pod\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} avg\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Pod Events\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"create avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#70dbed\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"delete avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e24d42\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"update avg\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"color\",\n                    \"value\": {\n                      \"fixedColor\": \"#e0f9d7\",\n                      \"mode\": \"fixed\"\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 198\n          },\n          \"id\": 122,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kubernetes_events_total{k8s_app=\\\"cilium\\\", scope=\\\"Node\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}} avg\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Node Events\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 205\n          },\n          \"id\": 118,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kubernetes_events_total{k8s_app=\\\"cilium\\\", scope=\\\"Service\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}}\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Service Events\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 205\n          },\n          \"id\": 120,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kubernetes_events_total{k8s_app=\\\"cilium\\\", scope=\\\"Endpoint\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}}\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Endpoints Events\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"barWidthFactor\": 0.6,\n                \"drawStyle\": \"bars\",\n                \"fillOpacity\": 100,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"linear\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"normal\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"links\": [],\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 80\n                  }\n                ]\n              },\n              \"unit\": \"opm\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 212\n          },\n          \"id\": 121,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [],\n              \"displayMode\": \"list\",\n              \"placement\": \"bottom\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"none\"\n            }\n          },\n          \"pluginVersion\": \"11.3.1\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${DS_PROMETHEUS}\"\n              },\n              \"expr\": \"avg(rate(cilium_kubernetes_events_total{k8s_app=\\\"cilium\\\", scope=\\\"Namespace\\\", pod=~\\\"$pod\\\"}[1m])) by (pod, action) * 60\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{action}}\",\n              \"refId\": \"B\"\n            }\n          ],\n          \"title\": \"Namespace Events\",\n          \"type\": \"timeseries\"\n        }\n      ],\n      \"preload\": false,\n      \"refresh\": \"\",\n      \"schemaVersion\": 40,\n      \"tags\": [],\n      \"templating\": {\n        \"list\": [\n          {\n            \"current\": {},\n            \"includeAll\": false,\n            \"label\": \"Prometheus\",\n            \"name\": \"DS_PROMETHEUS\",\n            \"options\": [],\n            \"query\": \"prometheus\",\n            \"refresh\": 1,\n            \"regex\": \"\",\n            \"type\": \"datasource\"\n          },\n          {\n            \"allValue\": \"cilium.*\",\n            \"current\": {\n              \"text\": \"All\",\n              \"value\": \"$__all\"\n            },\n            \"datasource\": {\n              \"type\": \"prometheus\",\n              \"uid\": \"${DS_PROMETHEUS}\"\n            },\n            \"definition\": \"label_values(cilium_version, pod)\",\n            \"includeAll\": true,\n            \"name\": \"pod\",\n            \"options\": [],\n            \"query\": \"label_values(cilium_version, pod)\",\n            \"refresh\": 2,\n            \"regex\": \"\",\n            \"sort\": 1,\n            \"type\": \"query\"\n          }\n        ]\n      },\n      \"time\": {\n        \"from\": \"now-30m\",\n        \"to\": \"now\"\n      },\n      \"timepicker\": {\n        \"refresh_intervals\": [\n          \"10s\",\n          \"30s\",\n          \"1m\",\n          \"5m\",\n          \"15m\",\n          \"30m\",\n          \"1h\",\n          \"2h\",\n          \"1d\"\n        ]\n      },\n      \"timezone\": \"utc\",\n      \"title\": \"Cilium Metrics\",\n      \"uid\": \"vtuWtdumz\",\n      \"version\": 1,\n      \"weekStart\": \"\"\n    }\nkind: ConfigMap\nmetadata:\n  annotations:\n    grafana_folder: kube-system\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-agent\n    app.kubernetes.io/part-of: cilium\n    grafana_dashboard: \"1\"\n    k8s-app: cilium\n  name: cilium-dashboard\n  namespace: kube-system\n---\napiVersion: v1\ndata:\n  cilium-operator-dashboard.json: |\n    {\n      \"__inputs\": [\n        {\n          \"name\": \"DS_PROMETHEUS\",\n          \"label\": \"prometheus\",\n          \"description\": \"\",\n          \"type\": \"datasource\",\n          \"pluginId\": \"prometheus\",\n          \"pluginName\": \"Prometheus\"\n        }\n      ],\n      \"annotations\": {\n        \"list\": [\n          {\n            \"builtIn\": 1,\n            \"datasource\": {\n              \"type\": \"datasource\",\n              \"uid\": \"grafana\"\n            },\n            \"enable\": true,\n            \"hide\": true,\n            \"iconColor\": \"rgba(0, 211, 255, 1)\",\n            \"name\": \"Annotations & Alerts\",\n            \"type\": \"dashboard\"\n          }\n        ]\n      },\n      \"editable\": true,\n      \"gnetId\": null,\n      \"graphTooltip\": 0,\n      \"id\": 8,\n      \"links\": [],\n      \"panels\": [\n        {\n          \"aliasColors\": {\n            \"avg\": \"#cffaff\"\n          },\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 0,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 0\n          },\n          \"hiddenSeries\": false,\n          \"id\": 24,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 5,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [\n            {\n              \"alias\": \"max\",\n              \"fillBelowTo\": \"min\",\n              \"lines\": false\n            },\n            {\n              \"alias\": \"min\",\n              \"lines\": false\n            }\n          ],\n          \"spaceLength\": 10,\n          \"stack\": false,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"min(irate(cilium_operator_process_cpu_seconds_total{io_cilium_app=\\\"operator\\\"}[1m])) by (pod) * 100\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"min\",\n              \"refId\": \"A\"\n            },\n            {\n              \"expr\": \"avg(irate(cilium_operator_process_cpu_seconds_total{io_cilium_app=\\\"operator\\\"}[1m])) by (pod) * 100\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"avg\",\n              \"refId\": \"B\"\n            },\n            {\n              \"expr\": \"max(irate(cilium_operator_process_cpu_seconds_total{io_cilium_app=\\\"operator\\\"}[1m])) by (pod) * 100\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"max\",\n              \"refId\": \"C\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"CPU Usage per node\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"percent\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"aliasColors\": {\n            \"MAX_resident_memory_bytes_max\": \"#e5ac0e\"\n          },\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 5,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 0\n          },\n          \"hiddenSeries\": false,\n          \"id\": 26,\n          \"legend\": {\n            \"alignAsTable\": false,\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"rightSide\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 5,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": false,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"avg(cilium_operator_process_resident_memory_bytes{io_cilium_app=\\\"operator\\\"})\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"AVG_resident_memory_bytes\",\n              \"refId\": \"C\"\n            },\n            {\n              \"expr\": \"max(cilium_operator_process_resident_memory_bytes{io_cilium_app=\\\"operator\\\"})\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"MAX_resident_memory_bytes_max\",\n              \"refId\": \"D\"\n            },\n            {\n              \"expr\": \"min(cilium_operator_process_resident_memory_bytes{io_cilium_app=\\\"operator\\\"})\",\n              \"format\": \"time_series\",\n              \"interval\": \"\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"MIN_resident_memory_bytes_min\",\n              \"refId\": \"E\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"Resident memory status\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"bytes\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"collapsed\": false,\n          \"datasource\": null,\n          \"gridPos\": {\n            \"h\": 1,\n            \"w\": 24,\n            \"x\": 0,\n            \"y\": 5\n          },\n          \"id\": 6,\n          \"panels\": [],\n          \"title\": \"IPAM\",\n          \"type\": \"row\"\n        },\n        {\n          \"aliasColors\": {},\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 6\n          },\n          \"hiddenSeries\": false,\n          \"id\": 8,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 2,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": true,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"avg(cilium_operator_ipam_ips) by (type)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{type}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"IP Addresses\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"aliasColors\": {},\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 6\n          },\n          \"hiddenSeries\": false,\n          \"id\": 10,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 2,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": false,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"rate(cilium_operator_ec2_api_duration_seconds_sum[1m])/rate(cilium_operator_ec2_api_duration_seconds_count[1m])\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{operation}} {{response_code}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"EC2 API Interactions\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"dtdurations\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"aliasColors\": {},\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 8,\n            \"x\": 0,\n            \"y\": 14\n          },\n          \"hiddenSeries\": false,\n          \"id\": 4,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 2,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": false,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"cilium_operator_ipam_nodes\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{category}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"Number of nodes\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"aliasColors\": {},\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 8,\n            \"x\": 8,\n            \"y\": 14\n          },\n          \"hiddenSeries\": false,\n          \"id\": 12,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 2,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": false,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"cilium_operator_ipam_available\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"interfaces\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"# interfaces with addresses available\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"aliasColors\": {},\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 7,\n            \"w\": 8,\n            \"x\": 16,\n            \"y\": 14\n          },\n          \"hiddenSeries\": false,\n          \"id\": 16,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 2,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": false,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"rate(cilium_operator_ipam_resync_total[1m])\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"operations\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"Metadata Resync Operations\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"ops\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"aliasColors\": {},\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 21\n          },\n          \"hiddenSeries\": false,\n          \"id\": 14,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 2,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": true,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"rate(cilium_operator_ec2_api_rate_limit_duration_seconds_sum[1m])/rate(cilium_operator_ec2_api_rate_limit_duration_seconds_count[1m])\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{operation}}\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"EC2 client side rate limiting\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"reqps\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        },\n        {\n          \"aliasColors\": {},\n          \"bars\": false,\n          \"dashLength\": 10,\n          \"dashes\": false,\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${DS_PROMETHEUS}\"\n          },\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {}\n            },\n            \"overrides\": []\n          },\n          \"fill\": 1,\n          \"fillGradient\": 0,\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 21\n          },\n          \"hiddenSeries\": false,\n          \"id\": 2,\n          \"legend\": {\n            \"avg\": false,\n            \"current\": false,\n            \"max\": false,\n            \"min\": false,\n            \"show\": true,\n            \"total\": false,\n            \"values\": false\n          },\n          \"lines\": true,\n          \"linewidth\": 1,\n          \"links\": [],\n          \"nullPointMode\": \"null\",\n          \"options\": {\n            \"dataLinks\": []\n          },\n          \"paceLength\": 10,\n          \"percentage\": false,\n          \"pointradius\": 2,\n          \"points\": false,\n          \"renderer\": \"flot\",\n          \"seriesOverrides\": [],\n          \"spaceLength\": 10,\n          \"stack\": false,\n          \"steppedLine\": false,\n          \"targets\": [\n            {\n              \"expr\": \"avg(rate(cilium_operator_ipam_interface_creation_ops[1m])) by (subnetId, status)\",\n              \"format\": \"time_series\",\n              \"intervalFactor\": 1,\n              \"legendFormat\": \"{{status}} ({{subnetId}})\",\n              \"refId\": \"A\"\n            }\n          ],\n          \"thresholds\": [],\n          \"timeFrom\": null,\n          \"timeRegions\": [],\n          \"timeShift\": null,\n          \"title\": \"Interface Creation\",\n          \"tooltip\": {\n            \"shared\": true,\n            \"sort\": 0,\n            \"value_type\": \"individual\"\n          },\n          \"type\": \"graph\",\n          \"xaxis\": {\n            \"buckets\": null,\n            \"mode\": \"time\",\n            \"name\": null,\n            \"show\": true,\n            \"values\": []\n          },\n          \"yaxes\": [\n            {\n              \"format\": \"ops\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            },\n            {\n              \"format\": \"short\",\n              \"label\": null,\n              \"logBase\": 1,\n              \"max\": null,\n              \"min\": null,\n              \"show\": true\n            }\n          ],\n          \"yaxis\": {\n            \"align\": false,\n            \"alignLevel\": null\n          }\n        }\n      ],\n      \"refresh\": false,\n      \"schemaVersion\": 25,\n      \"style\": \"dark\",\n      \"tags\": [],\n      \"templating\": {\n        \"list\": [\n          {\n            \"type\": \"datasource\",\n            \"name\": \"DS_PROMETHEUS\",\n            \"query\": \"prometheus\"\n          }\n        ]\n      },\n      \"time\": {\n        \"from\": \"now-30m\",\n        \"to\": \"now\"\n      },\n      \"timepicker\": {\n        \"refresh_intervals\": [\n          \"10s\",\n          \"30s\",\n          \"1m\",\n          \"5m\",\n          \"15m\",\n          \"30m\",\n          \"1h\",\n          \"2h\",\n          \"1d\"\n        ],\n        \"time_options\": [\n          \"5m\",\n          \"15m\",\n          \"1h\",\n          \"6h\",\n          \"12h\",\n          \"24h\",\n          \"2d\",\n          \"7d\",\n          \"30d\"\n        ]\n      },\n      \"timezone\": \"\",\n      \"title\": \"Cilium Operator\",\n      \"uid\": \"1GC0TT4Wz\",\n      \"version\": 2\n    }\nkind: ConfigMap\nmetadata:\n  annotations:\n    grafana_folder: kube-system\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-operator\n    app.kubernetes.io/part-of: cilium\n    grafana_dashboard: \"1\"\n    k8s-app: cilium\n  name: cilium-operator-dashboard\n  namespace: kube-system\n---\napiVersion: v1\ndata:\n  config.yaml: \"cluster-name: default\\npeer-service: \\\"hubble-peer.kube-system.svc.cluster.local.:443\\\"\\nlisten-address:\n    :4245\\ngops: true\\ngops-port: \\\"9893\\\"\\nretry-timeout: \\nsort-buffer-len-max:\n    \\nsort-buffer-drain-timeout: \\ntls-hubble-client-cert-file: /var/lib/hubble-relay/tls/client.crt\\ntls-hubble-client-key-file:\n    /var/lib/hubble-relay/tls/client.key\\ntls-hubble-server-ca-files: /var/lib/hubble-relay/tls/hubble-server-ca.crt\\n\\ndisable-server-tls:\n    true\\n\"\nkind: ConfigMap\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: hubble-relay-config\n  namespace: kube-system\n---\napiVersion: v1\ndata:\n  nginx.conf: |-\n    server {\n        listen       8081;\n        listen       [::]:8081;\n        server_name  localhost;\n        root /app;\n        index index.html;\n        client_max_body_size 1G;\n\n        location / {\n            proxy_set_header Host $host;\n            proxy_set_header X-Real-IP $remote_addr;\n\n            location /api {\n                proxy_http_version 1.1;\n                proxy_pass_request_headers on;\n                proxy_pass http://127.0.0.1:8090;\n            }\n            location / {\n                if ($http_user_agent ~* \"kube-probe\") { access_log off; }\n                # double `/index.html` is required here\n                try_files $uri $uri/ /index.html /index.html;\n            }\n\n            # Liveness probe\n            location /healthz {\n                access_log off;\n                add_header Content-Type text/plain;\n                return 200 'ok';\n            }\n        }\n    }\nkind: ConfigMap\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: hubble-ui-nginx\n  namespace: kube-system\n---\napiVersion: v1\ndata:\n  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lRR05WSERhd1ZsVU5TajJYOGx6dWZtekFOQmdrcWhraUc5dzBCQVFzRkFEQVUKTVJJd0VBWURWUVFERXdsRGFXeHBkVzBnUTBFd0hoY05NalV4TURJek1ESTFNakUxV2hjTk1qZ3hNREl5TURJMQpNakUxV2pBVU1SSXdFQVlEVlFRREV3bERhV3hwZFcwZ1EwRXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRQ2dpMG1FZ3pQVk5NRXAxUVMzZDl0bzBPTkZPMndpK1RYa28zcEFFNDJsQ2NGNWlWM3QKUnB2N3BlWHRMN05CU2NsTkRDSHNiRHNKQm9kRWU3N3BUbkNGcWNkZXgyUk1aV3B4Vmk4akd5V2FrdTdLdTFiRwoyRmFJcDM4RnZFQnNVRk1uY3RpMTBaMFJFYnNkUWJYcXZqRk0wQ0xxWmVPZlVGQ1pSU0VXWndOWjhraEg2V2J2CkhsSkExNjRjbjYydlNHY0htVDA2bk5FZjJ2dUFUZmhyYnZqYWdSQjFMK1dwbHRPNGlNUjVYU3UyVTNSMFB0Y0YKQ3JhNTlCdTN0K0lUc2c4dGMwaHRpc0gySjI4dWNWNndDMUtNQ3JPUWhwNUwzc3RXeTBoS01KT3RYclVXd1R0OApoUHBWREhBR0RxeHBoai9HUzVjRWdWNTlFM1pBeVRWMXpudlZBZ01CQUFHallUQmZNQTRHQTFVZER3RUIvd1FFCkF3SUNwREFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXcKQXdFQi96QWRCZ05WSFE0RUZnUVVCT04rOWY0NHExRk9MUmdnV3VTWTdLdEFOaUV3RFFZSktvWklodmNOQVFFTApCUUFEZ2dFQkFFU2xRTWs4blMvVWpnOURlVnNaT21ZRnJsQUFpK3NuN21JZ2x4eFJJWFRjamVOMkR6QUZjSW9pCktXcC9wajlKdmhFdHJ3b29KUkJSUCtzUnp3MjEwS3Z3ZlpJV1BZRU85MGREb2d0N2U2bTh6TFN3V0xDQ2EwWVgKK29sVjhMdHJOdjZXTElBVExpZWxQNDErZlVvSVJnZ0VGaitIcklUU1EzYjQ0Nng1UUZVa2pyYnprdmowMHNXaAoxeXBha21OWENlZFI1UEZKK3p0a05jL2VZQlU4MURGN0QxYW9jOVMwSXlRdkloa1Z1dHg3VzNIQUh4K2ZCUVJkClBBcGpvcGp5QzNhbTJMRHJUbFVJeU1hZWFZaUtvZGo5aFZuYzZKa3RrNXAwZFRsVnJZeU9nMnlsM2VVakI1ZDIKUmhQZ3lxTnU3R0xKenZmZzFoNHpkbGpZZ3pYcXo0VT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\n  ca.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBb0l0SmhJTXoxVFRCS2RVRXQzZmJhTkRqUlR0c0l2azE1S042UUJPTnBRbkJlWWxkCjdVYWIrNlhsN1MrelFVbkpUUXdoN0d3N0NRYUhSSHUrNlU1d2hhbkhYc2RrVEdWcWNWWXZJeHNsbXBMdXlydFcKeHRoV2lLZC9CYnhBYkZCVEozTFl0ZEdkRVJHN0hVRzE2cjR4VE5BaTZtWGpuMUJRbVVVaEZtY0RXZkpJUitsbQo3eDVTUU5ldUhKK3RyMGhuQjVrOU9welJIOXI3Z0UzNGEyNzQyb0VRZFMvbHFaYlR1SWpFZVYwcnRsTjBkRDdYCkJRcTJ1ZlFidDdmaUU3SVBMWE5JYllyQjlpZHZMbkZlc0F0U2pBcXprSWFlUzk3TFZzdElTakNUclY2MUZzRTcKZklUNlZReHdCZzZzYVlZL3hrdVhCSUZlZlJOMlFNazFkYzU3MVFJREFRQUJBb0lCQUFuSnBDQkhqWFBzcFBBagpkQWVwYjM5NjZMZ3lVTHZySEoyRlYvRXJJQUlWVDYzVXNaekRKc1JYVDJhLzl6bytRTjhKSTlKUm9PSENlNkd4CnQ2aHFwMUtHME1oVytLYnRzZWtaKzRLMDUzeCtnNzlwWDNkOC9mMlQxSnNwYUhZU0NaZkltU3l3akZaYmtlQk4KUHNXQ2RlZjhjbngrM0xzOFBzV3hZTHlJYUR4bC84QmgySFBFSFRsVEhVUzNMMkRXZGcybE1abjhaV1pCdVUycApET1pWVnB6WWlub3B1ekpJeFRvYk1TeDlMeFJGNVVDYnQ4MW0xRVNsT3R4YkEyTnRXSm9GQWs4VGhITnN3ZEFRCmU3dkt3NWdoKzYwbHhid2VjS1ViMjZGWnNSQzlOZXVFSy9TT1VTQ2ZGcURKU3o3eEkyWGthQVVncGZsbWFaM0IKOTRoREpaRUNnWUVBMVk0YnF3SzEvcVVSNC80NkhqdHJuSHVJRXRqY2dxaEpRamU1aVA1T1gxN0RWamsyU2pPOApSL2ZNTm9lMWhQUGZ6NmNlNC9JMmczS1dzTjVsWjVtMjhta3hWbmlITmRkNEcvQXhRdnFWeUZrS2d3bHFsd2FMCktIeVJwVWMxaFZLYmgxMDdSN3Fxd3N5ZTAwMlZaMnpDb055TDJzZXBvam5QM0xiNWhLazBQRTBDZ1lFQXdIUHQKUktWcFVnSzIrNkFVNHpteC8zN3l6OFc4WDVpMytJL213NWVuN0ZsSzQ3MXJXQjZmSm42dTlBZitQWTVVcWN4MApOY1BSMFpvK0JZdWtramdSVi9JZ1NVZ29sRXJ5QWt5dUFUcTZyazk1ejRPbkl1ekVsQXgxSE1Scyswd3JGK1RFCkdwbzAxY3QvY0xZTFFYTENvMHpSSXZGclNYRkdhdnFqQzd3ZjRha0NnWUJkYW5oMzZndXFoSks2NU82UFl2YkQKME5YSlNNdk02OGlBQ3RoQ01Od2ZvOWhXMDFnSVJYRkxHZjVlckNhZkxmN3RXdkdNVE52RHpGQld0akl0aTNRWAp2aVF5Nnk1YVF4THJSYnFHemc3UFFRUDBKaDVXU2lwOVgyQm1xQ3VsVW1sdVlUNFpObktVRytZdUVIWVdjK0QvCmRQcElqYWFLckRkZEdUMDA1cjlPMFFLQmdRQ3dIMmRjRXlTM2NOU1Vvb043RHluZWNBYzJMZmVlWk55NEZMbFMKOWs4dTlPaWNVcFVTSjdQdVByRk5rcU1SSWxoSXJGc05lUTlqaW95SDlxdTlSS0phb2JMNlhaY0ZYekRxK2RHawpQbUxwY3NJL0xuU2VlWi9NL1RtUUFoTGFSM0tJZzBzVUxWdDg3S2JNTjAxRnNBaC8rYVRMSGJUWm1WaWdQbzlJCkJmb0hRUUtCZ0UyaktBQVhXbi85bHhnZGh3aC9sRzBBYXIrSlErZVhVYW9nTFgveGJWeG5xQk5iMUFwYzhQRU4Ka09sUGJqKzlvQSthenpQaW9FY1F0bUpLR1p2VEp4K3FqUG9OdDZ3NUZhTzNJK1pvMzNwUlIxZkFqS3hGMDV2OApsV2huNG5kZWE5anpNKy9lOEJITGVaMG0vYkxoOWwzay9VckFNUGxGMDJCcDV1VTh6RFNqCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==\nkind: Secret\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: cilium-ca\n  namespace: kube-system\n---\napiVersion: v1\ndata:\n  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lRR05WSERhd1ZsVU5TajJYOGx6dWZtekFOQmdrcWhraUc5dzBCQVFzRkFEQVUKTVJJd0VBWURWUVFERXdsRGFXeHBkVzBnUTBFd0hoY05NalV4TURJek1ESTFNakUxV2hjTk1qZ3hNREl5TURJMQpNakUxV2pBVU1SSXdFQVlEVlFRREV3bERhV3hwZFcwZ1EwRXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRQ2dpMG1FZ3pQVk5NRXAxUVMzZDl0bzBPTkZPMndpK1RYa28zcEFFNDJsQ2NGNWlWM3QKUnB2N3BlWHRMN05CU2NsTkRDSHNiRHNKQm9kRWU3N3BUbkNGcWNkZXgyUk1aV3B4Vmk4akd5V2FrdTdLdTFiRwoyRmFJcDM4RnZFQnNVRk1uY3RpMTBaMFJFYnNkUWJYcXZqRk0wQ0xxWmVPZlVGQ1pSU0VXWndOWjhraEg2V2J2CkhsSkExNjRjbjYydlNHY0htVDA2bk5FZjJ2dUFUZmhyYnZqYWdSQjFMK1dwbHRPNGlNUjVYU3UyVTNSMFB0Y0YKQ3JhNTlCdTN0K0lUc2c4dGMwaHRpc0gySjI4dWNWNndDMUtNQ3JPUWhwNUwzc3RXeTBoS01KT3RYclVXd1R0OApoUHBWREhBR0RxeHBoai9HUzVjRWdWNTlFM1pBeVRWMXpudlZBZ01CQUFHallUQmZNQTRHQTFVZER3RUIvd1FFCkF3SUNwREFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXcKQXdFQi96QWRCZ05WSFE0RUZnUVVCT04rOWY0NHExRk9MUmdnV3VTWTdLdEFOaUV3RFFZSktvWklodmNOQVFFTApCUUFEZ2dFQkFFU2xRTWs4blMvVWpnOURlVnNaT21ZRnJsQUFpK3NuN21JZ2x4eFJJWFRjamVOMkR6QUZjSW9pCktXcC9wajlKdmhFdHJ3b29KUkJSUCtzUnp3MjEwS3Z3ZlpJV1BZRU85MGREb2d0N2U2bTh6TFN3V0xDQ2EwWVgKK29sVjhMdHJOdjZXTElBVExpZWxQNDErZlVvSVJnZ0VGaitIcklUU1EzYjQ0Nng1UUZVa2pyYnprdmowMHNXaAoxeXBha21OWENlZFI1UEZKK3p0a05jL2VZQlU4MURGN0QxYW9jOVMwSXlRdkloa1Z1dHg3VzNIQUh4K2ZCUVJkClBBcGpvcGp5QzNhbTJMRHJUbFVJeU1hZWFZaUtvZGo5aFZuYzZKa3RrNXAwZFRsVnJZeU9nMnlsM2VVakI1ZDIKUmhQZ3lxTnU3R0xKenZmZzFoNHpkbGpZZ3pYcXo0VT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\n  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURTVENDQWpHZ0F3SUJBZ0lSQUp0Rm03REQwby9ZcFVIVDNyRUszbmN3RFFZSktvWklodmNOQVFFTEJRQXcKRkRFU01CQUdBMVVFQXhNSlEybHNhWFZ0SUVOQk1CNFhEVEkxTVRBeU16QXlOVEl4TlZvWERUSTJNVEF5TXpBeQpOVEl4TlZvd0l6RWhNQjhHQTFVRUF3d1lLaTVvZFdKaWJHVXRjbVZzWVhrdVkybHNhWFZ0TG1sdk1JSUJJakFOCkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXZLTUFKZmt2dmhuMjZ3VXlpT1VUU3RIeFNxaVIKQkJsNlRBOHpBNHZVdk9XVGh5dGF5bGhjU2ZZZFBCemQ3SzkwdWFtdXhQNU1ZT3ltMHZaYlcxMVFnTE5rNDZtTgppM1Z2SVBwSEZyZ2lDeXM2ME1QY1Rra2QxVEZUT2FIWVJyeURIQU5SSzM5WVBjeWJ6ajlEc203NE9LeHRVTVlPCjdvYkphS2ZWbHZNSWMrUVJZTDNMdHQwMUcrOGpoRXFzM3ljbkRPRDU1SGVjMmlGZm5MQkpVendxR1FHVG55K3oKQ3NETG9OdlQ5Y0VDRXVMbjAwVkVaTGNjclUxdFROVDB1NzVUcnQ5STFWa3N1Q3lqYWlRZlRxblhNbEdDdHZjNgpKYXlPdW8xaWREYTNyanlEbEtUVE9mbjRNaXhwTmM3bHhpS3VUMURCakQ4WmhOa1h6ekh6UlZxOWxRSURBUUFCCm80R0dNSUdETUE0R0ExVWREd0VCL3dRRUF3SUZvREFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSUt3WUIKQlFVSEF3SXdEQVlEVlIwVEFRSC9CQUl3QURBZkJnTlZIU01FR0RBV2dCUUU0MzcxL2ppclVVNHRHQ0JhNUpqcwpxMEEySVRBakJnTlZIUkVFSERBYWdoZ3FMbWgxWW1Kc1pTMXlaV3hoZVM1amFXeHBkVzB1YVc4d0RRWUpLb1pJCmh2Y05BUUVMQlFBRGdnRUJBQ3lkNnA0YjYyd1U0WkQxNmtJRjhhM3owRXZyak9OTDAxaHFucWRtVW5QdTNwenYKRGpGQ2FKYm1iMkljWUpKc09rQTJRQVg5UnUvTGR4RHdMQlUzalk4dXFvazBOVFZySzRBcktQVGx2ZUlYcW9UYwpWSFovY1ZpREFRMFRLbjlEc0FWVjZvVWFxMXkxTFYrV2VXWWVuSWRCR0ZFT3JGVGQxVkE5R2pUd2pscGtoWXpZCks4OUl0V2JOdFQ4YnUvbEljeGJFMjZmT29HUlEvaWxLSDdBVzdBOEwwemY1Rk9xRlVqbHBPeVluMmlLSHdNVU8KWVlrVThVcUNEbmFRWmJCTXQ4cnVoRjRqUmRmVjFMamMyRDI0YnpMcFlQRlZIblAxaUNCTXpBdFAwdjJMczdUMAp5dXc4UFlGZ01FQXZqdFNtcW53WllEN0tMV2s3MU9VUXY4VWNDTzg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\n  tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBdktNQUpma3Z2aG4yNndVeWlPVVRTdEh4U3FpUkJCbDZUQTh6QTR2VXZPV1RoeXRhCnlsaGNTZllkUEJ6ZDdLOTB1YW11eFA1TVlPeW0wdlpiVzExUWdMTms0Nm1OaTNWdklQcEhGcmdpQ3lzNjBNUGMKVGtrZDFURlRPYUhZUnJ5REhBTlJLMzlZUGN5YnpqOURzbTc0T0t4dFVNWU83b2JKYUtmVmx2TUljK1FSWUwzTAp0dDAxRys4amhFcXMzeWNuRE9ENTVIZWMyaUZmbkxCSlV6d3FHUUdUbnkrekNzRExvTnZUOWNFQ0V1TG4wMFZFClpMY2NyVTF0VE5UMHU3NVRydDlJMVZrc3VDeWphaVFmVHFuWE1sR0N0dmM2SmF5T3VvMWlkRGEzcmp5RGxLVFQKT2ZuNE1peHBOYzdseGlLdVQxREJqRDhaaE5rWHp6SHpSVnE5bFFJREFRQUJBb0lCQUZkK3k0elJmaUdRN1lTcApUbjFNczV3YXNPN09MU1ZYby9BdmhKdjZlZHg4Sitla1ptSkFoZDRRZUJMdjJNZjF3aEJ6OGdxUllWLzdwSTFwCms0cFhTQVhLTDl1aFEzUVNMazkvaHdXMHRxV3prWDVQdXBuZE5DYzB6OE9GbkVtREd0VWRmTUxPT0dIQnkrcm8KVVVBc1ZKb0U4RmRzNW5RZ3RMOEVTZi9RRG5XaDRKNzg1NDF1dTM1akE0aEEzZ3pTVnZ3R1duUStUTzN1T3IrbwpKZ2d3SWM0Z1ljT0FMa1dzTldqRCtXNHNMbzhxY1lnV2RhaEhSRUNMeVFqazd2WVhzUG5TbXdJUFNwZnFKRTRTCjJyejl2NTV6cGwyLzIrdm9iWHRMTHFIcTB6RjhnMGFZbXdHdWp3VVZ5em5uUUhWMEVJNjFCTlZqWldwR1Y0WS8KV0hqcnhha0NnWUVBOUpDaFk1K0ZSSXdvUlpDR1FnTlVKczFHTkFPNHR0NGRjL1hyZjI4dTlYRUdBR25vZitSRQo5UkFCTUdLcWhvOG1oN3BWU0RDcEFwRkFLb2VVWndJMXhrVnpkMVlFSFlRbnMrMWhmU0VUb3Y3SEFZR01KOWNlCkk4KzRRZWhZRmNHRlhrS241R2I0YXYvZHYwVTd3T1NXWVRRU25BR2cyWEF0SXpQVC9oak9BOHNDZ1lFQXhYVHQKQVZoQlBueGFNZjA2MHBsQnJlcHZISDllWk11SDRhRjBuaGg3cmkyRG5sdjcrdHlPQ1Z0VTNsYmNHUVZlbnNRNwpwYVBOVVlyTHJVZ0JuSnNDRE9LbE1qanMwLzA0M0h5RHhJNXVYVlN0Zzg2OWVLWHZtNjVHak1uWEpSQTAzN3RLCjlEcCtrcVBPalQzUVVNa051Vzk2cjEyMlZFL3RuSzRzYnI3LzJCOENnWUVBclZ3NGl0M3hJZjRZTGZlY3MvNlkKRUVsQ2tteHc2Mi9YZ1BPNTA4T0VqZ2RvTWJMaFZJY0RPcFAxdzg2dEFtVkc4cjlxNUpsWnRMQXh3L1FIaGwxUwpzUkZhSUNXaEZTc3cyYUpUa05kNWkvaitLRnNrZHJsT2JDUTZnTDJxY3dHVEFKWlBYT0NCQjVnSUlDVjdqZWg3CmtMdlExVFZ5UjYvMHp4ZFdGckNPbUxFQ2dZQUszdDBOYmVacG9qNzA4WlFEZEJ5QmpwNS9XeU8vT05WS1ByRkUKNHVRc09xVThXcVFNczRlK1RDRG4vTEF4VUhKZEcwQ05aZTh2eGd4Z2hjNVE2TmU4RGQ0NlhaZnNNOHlsbHRWSwpSTzBlaGtMbk5zS0htZHNQSHhFVFB5bHhDT3RnUmRkaWlyWGRMTmQ2UHlUd3phREx6SzljYURSWmYrejg2em5XCi92em0wUUtCZ1FEZjljNlNtc1VHcGJYQTNHZ2xDQnBOUjIwK2dKVDBpUk1WdDVLcUtlNGxWUzF1aC9GUUJKcFYKbUxGUmQwR2ppakxPWG5TNEZxZ2R3OHd0Sm9UVnljUWpBbmowaXFLMG1MTklHdTJRNlpSQ291cWYxTlRudysyMwpWcDhwTit2ZWpKdGFEQnR1NnlzcVkvVE9wcm1ramc2ZGZvTDRRMVdua2Z2ZDh3T3NFWnRzK1E9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=\nkind: Secret\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: hubble-relay-client-certs\n  namespace: kube-system\ntype: kubernetes.io/tls\n---\napiVersion: v1\ndata:\n  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lRR05WSERhd1ZsVU5TajJYOGx6dWZtekFOQmdrcWhraUc5dzBCQVFzRkFEQVUKTVJJd0VBWURWUVFERXdsRGFXeHBkVzBnUTBFd0hoY05NalV4TURJek1ESTFNakUxV2hjTk1qZ3hNREl5TURJMQpNakUxV2pBVU1SSXdFQVlEVlFRREV3bERhV3hwZFcwZ1EwRXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRQ2dpMG1FZ3pQVk5NRXAxUVMzZDl0bzBPTkZPMndpK1RYa28zcEFFNDJsQ2NGNWlWM3QKUnB2N3BlWHRMN05CU2NsTkRDSHNiRHNKQm9kRWU3N3BUbkNGcWNkZXgyUk1aV3B4Vmk4akd5V2FrdTdLdTFiRwoyRmFJcDM4RnZFQnNVRk1uY3RpMTBaMFJFYnNkUWJYcXZqRk0wQ0xxWmVPZlVGQ1pSU0VXWndOWjhraEg2V2J2CkhsSkExNjRjbjYydlNHY0htVDA2bk5FZjJ2dUFUZmhyYnZqYWdSQjFMK1dwbHRPNGlNUjVYU3UyVTNSMFB0Y0YKQ3JhNTlCdTN0K0lUc2c4dGMwaHRpc0gySjI4dWNWNndDMUtNQ3JPUWhwNUwzc3RXeTBoS01KT3RYclVXd1R0OApoUHBWREhBR0RxeHBoai9HUzVjRWdWNTlFM1pBeVRWMXpudlZBZ01CQUFHallUQmZNQTRHQTFVZER3RUIvd1FFCkF3SUNwREFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXcKQXdFQi96QWRCZ05WSFE0RUZnUVVCT04rOWY0NHExRk9MUmdnV3VTWTdLdEFOaUV3RFFZSktvWklodmNOQVFFTApCUUFEZ2dFQkFFU2xRTWs4blMvVWpnOURlVnNaT21ZRnJsQUFpK3NuN21JZ2x4eFJJWFRjamVOMkR6QUZjSW9pCktXcC9wajlKdmhFdHJ3b29KUkJSUCtzUnp3MjEwS3Z3ZlpJV1BZRU85MGREb2d0N2U2bTh6TFN3V0xDQ2EwWVgKK29sVjhMdHJOdjZXTElBVExpZWxQNDErZlVvSVJnZ0VGaitIcklUU1EzYjQ0Nng1UUZVa2pyYnprdmowMHNXaAoxeXBha21OWENlZFI1UEZKK3p0a05jL2VZQlU4MURGN0QxYW9jOVMwSXlRdkloa1Z1dHg3VzNIQUh4K2ZCUVJkClBBcGpvcGp5QzNhbTJMRHJUbFVJeU1hZWFZaUtvZGo5aFZuYzZKa3RrNXAwZFRsVnJZeU9nMnlsM2VVakI1ZDIKUmhQZ3lxTnU3R0xKenZmZzFoNHpkbGpZZ3pYcXo0VT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\n  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURWakNDQWo2Z0F3SUJBZ0lRZXZ0TVhBTTc3R01sZnZ4QUROY1F0ekFOQmdrcWhraUc5dzBCQVFzRkFEQVUKTVJJd0VBWURWUVFERXdsRGFXeHBkVzBnUTBFd0hoY05NalV4TURJek1ESTFNakUxV2hjTk1qWXhNREl6TURJMQpNakUxV2pBcU1TZ3dKZ1lEVlFRRERCOHFMbVJsWm1GMWJIUXVhSFZpWW14bExXZHljR011WTJsc2FYVnRMbWx2Ck1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdm9VVDFrMWlUMzJSWkdxMVRhTisKQ0gxMzNCaEFFS0NMY3ZsbFRsZHZISGY0a2VOR2k4YlpOeHZ1Rk5ULzJIdU5wSGVjTnJ1VWlPL1R3YVRDMThOSApCZ3p6Y0pxMjdyQnZGTGN3b2pLYUFLcTN5VTVSYy9wZkVBc2U3WkRsQy9Id0NMc0gxdUpOMmdyaEFDd0pyY3k3ClM4SG04Z05wUlNwY2Z4eXd6bkthRHdDdXQ0RlFMRzFrOW1SaHkxR0Y4Q2xPV3NITEtReTRXN2ZmdDFvT0FWRWsKWUpzRlUxMzRjSnJESkpEUDBzSlBCbjZETlAvOGozZEtsWWczOHVaMUVjNTNsRzN1K0htcjZzRkNpdm5SYzc5NgpzTWllQTROWlV0UHNMaDZRcGkzTzI2N3dBMVdETWxxMmFHdlFMV3BOZXhCTlNMK21xT01iVWV3c1EwR2NkVG51CjF3SURBUUFCbzRHTk1JR0tNQTRHQTFVZER3RUIvd1FFQXdJRm9EQWRCZ05WSFNVRUZqQVVCZ2dyQmdFRkJRY0QKQVFZSUt3WUJCUVVIQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JRRTQzNzEvamlyVVU0dApHQ0JhNUpqc3EwQTJJVEFxQmdOVkhSRUVJekFoZ2g4cUxtUmxabUYxYkhRdWFIVmlZbXhsTFdkeWNHTXVZMmxzCmFYVnRMbWx2TUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFDVmNwSGZPYjBoaGpIa2ZWT3J3dE9CRU0vaEpuRWQKTnFwSHpLWGZXQU9YYTUvV0piQnFaVWt0bFdDME9nT2RoT2ZvaEl5cVErVks5Z3hYWDUwejVFUHpSYzQ5bGwrdApjbWJsaG5JVS9HbGpYeWhwRHM0Qit5Q2JYOUN0djJkNmxTS216M1RCSmF0TUxUeXBvRG85aWxUVFp0cXJ2T1dtClF2dzRsUmxLc0FLVW5PeDN4cGExenNxRTVJaENod1REeXkyU1FJbmtGYVhkdE0wbm9hckM2Vk9VaXhJOEo3Q0EKZEhWRVFtR2VCK045TnFjV1oyN3duTWNQL1RSb3ZFVTBMdFpULzVHUzgyNm1pV2dyM1E2MXkvQU4yZ3QwRXZXRApoRS8wMWxOWENMenJjNjN3K09mN05HYmFWWDgrK0xUSFRXQWdBY0k3eXNDbXFQa2VXUkpGZEl6UAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\n  tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBdm9VVDFrMWlUMzJSWkdxMVRhTitDSDEzM0JoQUVLQ0xjdmxsVGxkdkhIZjRrZU5HCmk4YlpOeHZ1Rk5ULzJIdU5wSGVjTnJ1VWlPL1R3YVRDMThOSEJnenpjSnEyN3JCdkZMY3dvakthQUtxM3lVNVIKYy9wZkVBc2U3WkRsQy9Id0NMc0gxdUpOMmdyaEFDd0pyY3k3UzhIbThnTnBSU3BjZnh5d3puS2FEd0N1dDRGUQpMRzFrOW1SaHkxR0Y4Q2xPV3NITEtReTRXN2ZmdDFvT0FWRWtZSnNGVTEzNGNKckRKSkRQMHNKUEJuNkROUC84CmozZEtsWWczOHVaMUVjNTNsRzN1K0htcjZzRkNpdm5SYzc5NnNNaWVBNE5aVXRQc0xoNlFwaTNPMjY3d0ExV0QKTWxxMmFHdlFMV3BOZXhCTlNMK21xT01iVWV3c1EwR2NkVG51MXdJREFRQUJBb0lCQUJNWnI3Y2JibEMrZ1FDMQpPMVNtU3h0a3kzWElXZkU3ZHpUaFVKNW9ZUE9xQ2hudUtZTnRQY0pWb3RVa2Z1WGdOU29ZOG1pcnFQbzFqbUEvCjVCSW5qMkQwUHNVUG1HbHVUTTlNaDZ3QWhnb0NhTnlJdW9mTEZtbGxyckJ0M0s0Smo3YXJCdC9YTTZ1T3phZEIKR0ZOUlR0eGdlekVtS3hGTHdaYmVIeWV1RVBNOGw2ZEJsWHhxbVNiOHk3YWRkQ3lOTkNJQ1JMNU01VDQ3M2JxbwprN2tXWWpVUENkQThXdWUxRHM1YXZoLzcxZEFiZG1NREFTTHNONXJMdGRHSzNKZlhWOVd3dzhKemc5cVJsSGJLCktuT01oTFJRU21RN3pLOW1iK3BrY054MHFDTkF0VnBkSWhSNnozRU4zbjhGL2taT25MWmlzdzB4d0F0QVM4RmUKOU94eGxFa0NnWUVBMkFCNVdTc1VtQy9DcXVIWEdSVjdPcTluWU9ZNmFPZXR3VkdPYUNrLy9RMkFkMFN1QzUrUwpmUDVBMXN0ZUNNak9rbE5NdGZGTGRaMm9XUVVFYTg2QzBtWGRoTnFrbnlucnhKZmxuMHdKb0Y2Y1VCc2xMWEYrCjdQL0NqcFUwSTdPN0VycDVIOWxWMTlkcjU1Tjc1anJkdVlsSkF2cTQvMXhLSnB3cDNrOEltTVVDZ1lFQTRjeWkKSTNtY0E5SWd1RGlEd2pJdEc4cVYvSGVReDRUdXByakdXTlBEa1JlTHNneHJ1S2ZXUFE0aVNoaDQxMzlROUxITQpySWp5MVozOHp6Uk5OSVg5V3U0WWowcTArS3ZLUGs3N0tNYXhrZXZYNksvMGQ4a05wS25sc1lpbVE3MGZPNHZiCnZBRHczeGRZVWZsMlpndFE4UW5YUE5YSTNIbklQcHFJS21MR0N1c0NnWUFjRzNPdTlyd25VWSt6VE5BQW81cjEKZC8ycnprbXJmUHBQUFoyYVVFUFRXZjV0aHJKZk1OU1BEMGJBckpYLzdxRnl5UVFpYU5PNDZsc051bWxvM2VhSQpHbGxKQUdxTGk1anliQkdsT08vSHZvZjRwSStoNmpMcUJCMzlEODFKR0FvdjFiUU5RT3E2dTMxL0ZPSDZnNDUyCnBqYXAvSlkySkh4QnFmQ0l6U0FCUVFLQmdGanozcVFQRW5GRzVIRHVncW1NVHN6MkFDUlhqZ2Vyek1DTlprWTAKRm9VZ08zNUcrbURpYmJuYnlaSmJGYS8vamdyM3lHUG9CNUkwRFJZcnlvWjRpcGk1MTU4TGxVT3BtYUQyU0dlRgo3d3BIV09WbisrejhuWTFUQ1JQcGUyYVFLSyt5cHp2bk92MElHMWtmNTQ3SHdubFNvU0pzTGhiOU91Kyt2UW5GCm83TkZBb0dBR0luV1NMMjZDeWdqQWNLY2ZwMXN5TFlEeWVsUXc4U0lEV2tUNjVUbmlObldkNWZSLzlybTRBQzUKQXRtVitDMGpkMHJPZGJTUGYxMnNzakRDZk5icjJJdmVPWENobHJVVTN5ZUlmK09xTkkvdXcxWVZsOHBya2duNgpQdFRBdjh4RVNuUTFHWkVIZzlvcGlSVXczNWNaYXVCOVc3MlhpNU5YTU8wZ3lHdnJmWlE9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==\nkind: Secret\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n  name: hubble-server-certs\n  namespace: kube-system\ntype: kubernetes.io/tls\n---\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-agent\n    app.kubernetes.io/part-of: cilium\n    k8s-app: cilium\n  name: cilium-agent\n  namespace: kube-system\nspec:\n  clusterIP: None\n  ports:\n  - name: metrics\n    port: 9962\n    protocol: TCP\n    targetPort: prometheus\n  - name: envoy-metrics\n    port: 9964\n    protocol: TCP\n    targetPort: envoy-metrics\n  selector:\n    k8s-app: cilium\n  type: ClusterIP\n---\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-operator\n    app.kubernetes.io/part-of: cilium\n    io.cilium/app: operator\n    name: cilium-operator\n  name: cilium-operator\n  namespace: kube-system\nspec:\n  clusterIP: None\n  ports:\n  - name: metrics\n    port: 9963\n    protocol: TCP\n    targetPort: prometheus\n  selector:\n    io.cilium/app: operator\n    name: cilium-operator\n  type: ClusterIP\n---\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: hubble-peer\n    app.kubernetes.io/part-of: cilium\n    k8s-app: cilium\n  name: hubble-peer\n  namespace: kube-system\nspec:\n  internalTrafficPolicy: Local\n  ports:\n  - name: peer-service\n    port: 443\n    protocol: TCP\n    targetPort: 4244\n  selector:\n    k8s-app: cilium\n---\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: hubble-relay\n    app.kubernetes.io/part-of: cilium\n    k8s-app: hubble-relay\n  name: hubble-relay\n  namespace: kube-system\nspec:\n  ports:\n  - port: 80\n    protocol: TCP\n    targetPort: grpc\n  selector:\n    k8s-app: hubble-relay\n  type: ClusterIP\n---\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: hubble-ui\n    app.kubernetes.io/part-of: cilium\n    k8s-app: hubble-ui\n  name: hubble-ui\n  namespace: kube-system\nspec:\n  ports:\n  - name: http\n    port: 80\n    targetPort: 8081\n  selector:\n    k8s-app: hubble-ui\n  type: ClusterIP\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-operator\n    app.kubernetes.io/part-of: cilium\n    io.cilium/app: operator\n    name: cilium-operator\n  name: cilium-operator\n  namespace: kube-system\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      io.cilium/app: operator\n      name: cilium-operator\n  strategy:\n    rollingUpdate:\n      maxSurge: 25%\n      maxUnavailable: 50%\n    type: RollingUpdate\n  template:\n    metadata:\n      annotations:\n        cilium.io/cilium-configmap-checksum: 247029c5d7a8d1277a2d60ee776629b6941eeb9c26eeb0ec407ff96803e89333\n      labels:\n        app.kubernetes.io/name: cilium-operator\n        app.kubernetes.io/part-of: cilium\n        io.cilium/app: operator\n        name: cilium-operator\n    spec:\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchLabels:\n                io.cilium/app: operator\n            topologyKey: kubernetes.io/hostname\n      automountServiceAccountToken: true\n      containers:\n      - args:\n        - --config-dir=/tmp/cilium/config-map\n        - --debug=$(CILIUM_DEBUG)\n        command:\n        - cilium-operator-generic\n        env:\n        - name: K8S_NODE_NAME\n          valueFrom:\n            fieldRef:\n              apiVersion: v1\n              fieldPath: spec.nodeName\n        - name: CILIUM_K8S_NAMESPACE\n          valueFrom:\n            fieldRef:\n              apiVersion: v1\n              fieldPath: metadata.namespace\n        - name: CILIUM_DEBUG\n          valueFrom:\n            configMapKeyRef:\n              key: debug\n              name: cilium-config\n              optional: true\n        - name: KUBERNETES_SERVICE_HOST\n          value: 127.0.0.1\n        - name: KUBERNETES_SERVICE_PORT\n          value: \"7445\"\n        image: quay.io/cilium/operator-generic:v1.18.2@sha256:cb4e4ffc5789fd5ff6a534e3b1460623df61cba00f5ea1c7b40153b5efb81805\n        imagePullPolicy: IfNotPresent\n        livenessProbe:\n          httpGet:\n            host: 127.0.0.1\n            path: /healthz\n            port: 9234\n            scheme: HTTP\n          initialDelaySeconds: 60\n          periodSeconds: 10\n          timeoutSeconds: 3\n        name: cilium-operator\n        ports:\n        - containerPort: 9963\n          hostPort: 9963\n          name: prometheus\n          protocol: TCP\n        readinessProbe:\n          failureThreshold: 5\n          httpGet:\n            host: 127.0.0.1\n            path: /healthz\n            port: 9234\n            scheme: HTTP\n          initialDelaySeconds: 0\n          periodSeconds: 5\n          timeoutSeconds: 3\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /tmp/cilium/config-map\n          name: cilium-config-path\n          readOnly: true\n      hostNetwork: true\n      nodeSelector:\n        kubernetes.io/os: linux\n      priorityClassName: system-cluster-critical\n      restartPolicy: Always\n      securityContext:\n        seccompProfile:\n          type: RuntimeDefault\n      serviceAccountName: cilium-operator\n      tolerations:\n      - key: node-role.kubernetes.io/control-plane\n        operator: Exists\n      - key: node-role.kubernetes.io/master\n        operator: Exists\n      - key: node.kubernetes.io/not-ready\n        operator: Exists\n      - key: node.cloudprovider.kubernetes.io/uninitialized\n        operator: Exists\n      - key: node.cilium.io/agent-not-ready\n        operator: Exists\n      volumes:\n      - configMap:\n          name: cilium-config\n        name: cilium-config-path\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: hubble-relay\n    app.kubernetes.io/part-of: cilium\n    k8s-app: hubble-relay\n  name: hubble-relay\n  namespace: kube-system\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      k8s-app: hubble-relay\n  strategy:\n    rollingUpdate:\n      maxUnavailable: 1\n    type: RollingUpdate\n  template:\n    metadata:\n      annotations: null\n      labels:\n        app.kubernetes.io/name: hubble-relay\n        app.kubernetes.io/part-of: cilium\n        k8s-app: hubble-relay\n    spec:\n      affinity:\n        podAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchLabels:\n                k8s-app: cilium\n            topologyKey: kubernetes.io/hostname\n      automountServiceAccountToken: false\n      containers:\n      - args:\n        - serve\n        command:\n        - hubble-relay\n        image: quay.io/cilium/hubble-relay:v1.18.2@sha256:6079308ee15e44dff476fb522612732f7c5c4407a1017bc3470916242b0405ac\n        imagePullPolicy: IfNotPresent\n        livenessProbe:\n          failureThreshold: 12\n          grpc:\n            port: 4222\n          initialDelaySeconds: 10\n          periodSeconds: 10\n          timeoutSeconds: 10\n        name: hubble-relay\n        ports:\n        - containerPort: 4245\n          name: grpc\n        readinessProbe:\n          grpc:\n            port: 4222\n          timeoutSeconds: 3\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          runAsGroup: 65532\n          runAsNonRoot: true\n          runAsUser: 65532\n          seccompProfile:\n            type: RuntimeDefault\n        startupProbe:\n          failureThreshold: 20\n          grpc:\n            port: 4222\n          initialDelaySeconds: 10\n          periodSeconds: 3\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /etc/hubble-relay\n          name: config\n          readOnly: true\n        - mountPath: /var/lib/hubble-relay/tls\n          name: tls\n          readOnly: true\n      nodeSelector:\n        kubernetes.io/os: linux\n      priorityClassName: null\n      restartPolicy: Always\n      securityContext:\n        fsGroup: 65532\n        seccompProfile:\n          type: RuntimeDefault\n      serviceAccountName: hubble-relay\n      terminationGracePeriodSeconds: 1\n      volumes:\n      - configMap:\n          items:\n          - key: config.yaml\n            path: config.yaml\n          name: hubble-relay-config\n        name: config\n      - name: tls\n        projected:\n          defaultMode: 256\n          sources:\n          - secret:\n              items:\n              - key: tls.crt\n                path: client.crt\n              - key: tls.key\n                path: client.key\n              - key: ca.crt\n                path: hubble-server-ca.crt\n              name: hubble-relay-client-certs\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: hubble-ui\n    app.kubernetes.io/part-of: cilium\n    k8s-app: hubble-ui\n  name: hubble-ui\n  namespace: kube-system\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      k8s-app: hubble-ui\n  strategy:\n    rollingUpdate:\n      maxUnavailable: 1\n    type: RollingUpdate\n  template:\n    metadata:\n      annotations: null\n      labels:\n        app.kubernetes.io/name: hubble-ui\n        app.kubernetes.io/part-of: cilium\n        k8s-app: hubble-ui\n    spec:\n      automountServiceAccountToken: true\n      containers:\n      - image: quay.io/cilium/hubble-ui:v0.13.3@sha256:661d5de7050182d495c6497ff0b007a7a1e379648e60830dd68c4d78ae21761d\n        imagePullPolicy: IfNotPresent\n        livenessProbe:\n          httpGet:\n            path: /healthz\n            port: 8081\n        name: frontend\n        ports:\n        - containerPort: 8081\n          name: http\n        readinessProbe:\n          httpGet:\n            path: /\n            port: 8081\n        securityContext:\n          allowPrivilegeEscalation: false\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /etc/nginx/conf.d/default.conf\n          name: hubble-ui-nginx-conf\n          subPath: nginx.conf\n        - mountPath: /tmp\n          name: tmp-dir\n      - env:\n        - name: EVENTS_SERVER_PORT\n          value: \"8090\"\n        - name: FLOWS_API_ADDR\n          value: hubble-relay:80\n        image: quay.io/cilium/hubble-ui-backend:v0.13.3@sha256:db1454e45dc39ca41fbf7cad31eec95d99e5b9949c39daaad0fa81ef29d56953\n        imagePullPolicy: IfNotPresent\n        name: backend\n        ports:\n        - containerPort: 8090\n          name: grpc\n        securityContext:\n          allowPrivilegeEscalation: false\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts: null\n      nodeSelector:\n        kubernetes.io/os: linux\n      priorityClassName: null\n      securityContext:\n        fsGroup: 1001\n        runAsGroup: 1001\n        runAsUser: 1001\n      serviceAccountName: hubble-ui\n      volumes:\n      - configMap:\n          defaultMode: 420\n          name: hubble-ui-nginx\n        name: hubble-ui-nginx-conf\n      - emptyDir: {}\n        name: tmp-dir\n---\napiVersion: apps/v1\nkind: DaemonSet\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-agent\n    app.kubernetes.io/part-of: cilium\n    k8s-app: cilium\n  name: cilium\n  namespace: kube-system\nspec:\n  selector:\n    matchLabels:\n      k8s-app: cilium\n  template:\n    metadata:\n      annotations:\n        cilium.io/cilium-configmap-checksum: 247029c5d7a8d1277a2d60ee776629b6941eeb9c26eeb0ec407ff96803e89333\n        kubectl.kubernetes.io/default-container: cilium-agent\n      labels:\n        app.kubernetes.io/name: cilium-agent\n        app.kubernetes.io/part-of: cilium\n        k8s-app: cilium\n    spec:\n      affinity:\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchLabels:\n                k8s-app: cilium\n            topologyKey: kubernetes.io/hostname\n      automountServiceAccountToken: true\n      containers:\n      - args:\n        - --config-dir=/tmp/cilium/config-map\n        command:\n        - cilium-agent\n        env:\n        - name: K8S_NODE_NAME\n          valueFrom:\n            fieldRef:\n              apiVersion: v1\n              fieldPath: spec.nodeName\n        - name: CILIUM_K8S_NAMESPACE\n          valueFrom:\n            fieldRef:\n              apiVersion: v1\n              fieldPath: metadata.namespace\n        - name: CILIUM_CLUSTERMESH_CONFIG\n          value: /var/lib/cilium/clustermesh/\n        - name: GOMEMLIMIT\n          valueFrom:\n            resourceFieldRef:\n              divisor: \"1\"\n              resource: limits.memory\n        - name: KUBERNETES_SERVICE_HOST\n          value: 127.0.0.1\n        - name: KUBERNETES_SERVICE_PORT\n          value: \"7445\"\n        - name: KUBE_CLIENT_BACKOFF_BASE\n          value: \"1\"\n        - name: KUBE_CLIENT_BACKOFF_DURATION\n          value: \"120\"\n        image: quay.io/cilium/cilium:v1.18.2@sha256:858f807ea4e20e85e3ea3240a762e1f4b29f1cb5bbd0463b8aa77e7b097c0667\n        imagePullPolicy: IfNotPresent\n        lifecycle:\n          postStart:\n            exec:\n              command:\n              - bash\n              - -c\n              - |\n                set -o errexit\n                set -o pipefail\n                set -o nounset\n\n                # When running in AWS ENI mode, it's likely that 'aws-node' has\n                # had a chance to install SNAT iptables rules. These can result\n                # in dropped traffic, so we should attempt to remove them.\n                # We do it using a 'postStart' hook since this may need to run\n                # for nodes which might have already been init'ed but may still\n                # have dangling rules. This is safe because there are no\n                # dependencies on anything that is part of the startup script\n                # itself, and can be safely run multiple times per node (e.g. in\n                # case of a restart).\n                if [[ \"$(iptables-save | grep -E -c 'AWS-SNAT-CHAIN|AWS-CONNMARK-CHAIN')\" != \"0\" ]];\n                then\n                    echo 'Deleting iptables rules created by the AWS CNI VPC plugin'\n                    iptables-save | grep -E -v 'AWS-SNAT-CHAIN|AWS-CONNMARK-CHAIN' | iptables-restore\n                fi\n                echo 'Done!'\n          preStop:\n            exec:\n              command:\n              - /cni-uninstall.sh\n        livenessProbe:\n          failureThreshold: 10\n          httpGet:\n            host: 127.0.0.1\n            httpHeaders:\n            - name: brief\n              value: \"true\"\n            - name: require-k8s-connectivity\n              value: \"false\"\n            path: /healthz\n            port: 9879\n            scheme: HTTP\n          periodSeconds: 30\n          successThreshold: 1\n          timeoutSeconds: 5\n        name: cilium-agent\n        ports:\n        - containerPort: 4244\n          hostPort: 4244\n          name: peer-service\n          protocol: TCP\n        - containerPort: 9962\n          hostPort: 9962\n          name: prometheus\n          protocol: TCP\n        - containerPort: 9964\n          hostPort: 9964\n          name: envoy-metrics\n          protocol: TCP\n        readinessProbe:\n          failureThreshold: 3\n          httpGet:\n            host: 127.0.0.1\n            httpHeaders:\n            - name: brief\n              value: \"true\"\n            path: /healthz\n            port: 9879\n            scheme: HTTP\n          periodSeconds: 30\n          successThreshold: 1\n          timeoutSeconds: 5\n        securityContext:\n          capabilities:\n            add:\n            - CHOWN\n            - KILL\n            - NET_ADMIN\n            - NET_RAW\n            - IPC_LOCK\n            - SYS_ADMIN\n            - SYS_RESOURCE\n            - PERFMON\n            - BPF\n            - DAC_OVERRIDE\n            - FOWNER\n            - SETGID\n            - SETUID\n            drop:\n            - ALL\n          seLinuxOptions:\n            level: s0\n            type: spc_t\n        startupProbe:\n          failureThreshold: 300\n          httpGet:\n            host: 127.0.0.1\n            httpHeaders:\n            - name: brief\n              value: \"true\"\n            path: /healthz\n            port: 9879\n            scheme: HTTP\n          initialDelaySeconds: 5\n          periodSeconds: 2\n          successThreshold: 1\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /host/proc/sys/net\n          name: host-proc-sys-net\n        - mountPath: /host/proc/sys/kernel\n          name: host-proc-sys-kernel\n        - mountPath: /sys/fs/bpf\n          mountPropagation: HostToContainer\n          name: bpf-maps\n        - mountPath: /sys/fs/cgroup\n          name: cilium-cgroup\n        - mountPath: /var/run/cilium\n          name: cilium-run\n        - mountPath: /var/run/cilium/netns\n          mountPropagation: HostToContainer\n          name: cilium-netns\n        - mountPath: /host/etc/cni/net.d\n          name: etc-cni-netd\n        - mountPath: /var/lib/cilium/clustermesh\n          name: clustermesh-secrets\n          readOnly: true\n        - mountPath: /lib/modules\n          name: lib-modules\n          readOnly: true\n        - mountPath: /run/xtables.lock\n          name: xtables-lock\n        - mountPath: /var/lib/cilium/tls/hubble\n          name: hubble-tls\n          readOnly: true\n        - mountPath: /tmp\n          name: tmp\n      hostNetwork: true\n      initContainers:\n      - command:\n        - cilium-dbg\n        - build-config\n        env:\n        - name: K8S_NODE_NAME\n          valueFrom:\n            fieldRef:\n              apiVersion: v1\n              fieldPath: spec.nodeName\n        - name: CILIUM_K8S_NAMESPACE\n          valueFrom:\n            fieldRef:\n              apiVersion: v1\n              fieldPath: metadata.namespace\n        - name: KUBERNETES_SERVICE_HOST\n          value: 127.0.0.1\n        - name: KUBERNETES_SERVICE_PORT\n          value: \"7445\"\n        image: quay.io/cilium/cilium:v1.18.2@sha256:858f807ea4e20e85e3ea3240a762e1f4b29f1cb5bbd0463b8aa77e7b097c0667\n        imagePullPolicy: IfNotPresent\n        name: config\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /tmp\n          name: tmp\n      - command:\n        - sh\n        - -ec\n        - |\n          cp /usr/bin/cilium-sysctlfix /hostbin/cilium-sysctlfix;\n          nsenter --mount=/hostproc/1/ns/mnt \"${BIN_PATH}/cilium-sysctlfix\";\n          rm /hostbin/cilium-sysctlfix\n        env:\n        - name: BIN_PATH\n          value: /opt/cni/bin\n        image: quay.io/cilium/cilium:v1.18.2@sha256:858f807ea4e20e85e3ea3240a762e1f4b29f1cb5bbd0463b8aa77e7b097c0667\n        imagePullPolicy: IfNotPresent\n        name: apply-sysctl-overwrites\n        securityContext:\n          capabilities:\n            add:\n            - SYS_ADMIN\n            - SYS_CHROOT\n            - SYS_PTRACE\n            drop:\n            - ALL\n          seLinuxOptions:\n            level: s0\n            type: spc_t\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /hostproc\n          name: hostproc\n        - mountPath: /hostbin\n          name: cni-path\n      - args:\n        - mount | grep \"/sys/fs/bpf type bpf\" || mount -t bpf bpf /sys/fs/bpf\n        command:\n        - /bin/bash\n        - -c\n        - --\n        image: quay.io/cilium/cilium:v1.18.2@sha256:858f807ea4e20e85e3ea3240a762e1f4b29f1cb5bbd0463b8aa77e7b097c0667\n        imagePullPolicy: IfNotPresent\n        name: mount-bpf-fs\n        securityContext:\n          privileged: true\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /sys/fs/bpf\n          mountPropagation: Bidirectional\n          name: bpf-maps\n      - command:\n        - /init-container.sh\n        env:\n        - name: CILIUM_ALL_STATE\n          valueFrom:\n            configMapKeyRef:\n              key: clean-cilium-state\n              name: cilium-config\n              optional: true\n        - name: CILIUM_BPF_STATE\n          valueFrom:\n            configMapKeyRef:\n              key: clean-cilium-bpf-state\n              name: cilium-config\n              optional: true\n        - name: WRITE_CNI_CONF_WHEN_READY\n          valueFrom:\n            configMapKeyRef:\n              key: write-cni-conf-when-ready\n              name: cilium-config\n              optional: true\n        - name: KUBERNETES_SERVICE_HOST\n          value: 127.0.0.1\n        - name: KUBERNETES_SERVICE_PORT\n          value: \"7445\"\n        image: quay.io/cilium/cilium:v1.18.2@sha256:858f807ea4e20e85e3ea3240a762e1f4b29f1cb5bbd0463b8aa77e7b097c0667\n        imagePullPolicy: IfNotPresent\n        name: clean-cilium-state\n        securityContext:\n          capabilities:\n            add:\n            - NET_ADMIN\n            - SYS_ADMIN\n            - SYS_RESOURCE\n            drop:\n            - ALL\n          seLinuxOptions:\n            level: s0\n            type: spc_t\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /sys/fs/bpf\n          name: bpf-maps\n        - mountPath: /sys/fs/cgroup\n          mountPropagation: HostToContainer\n          name: cilium-cgroup\n        - mountPath: /var/run/cilium\n          name: cilium-run\n      - command:\n        - /install-plugin.sh\n        image: quay.io/cilium/cilium:v1.18.2@sha256:858f807ea4e20e85e3ea3240a762e1f4b29f1cb5bbd0463b8aa77e7b097c0667\n        imagePullPolicy: IfNotPresent\n        name: install-cni-binaries\n        resources:\n          requests:\n            cpu: 100m\n            memory: 10Mi\n        securityContext:\n          capabilities:\n            drop:\n            - ALL\n          seLinuxOptions:\n            level: s0\n            type: spc_t\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /host/opt/cni/bin\n          name: cni-path\n      nodeSelector:\n        kubernetes.io/os: linux\n      priorityClassName: system-node-critical\n      restartPolicy: Always\n      securityContext:\n        appArmorProfile:\n          type: Unconfined\n        seccompProfile:\n          type: Unconfined\n      serviceAccountName: cilium\n      terminationGracePeriodSeconds: 1\n      tolerations:\n      - operator: Exists\n      volumes:\n      - emptyDir: {}\n        name: tmp\n      - hostPath:\n          path: /var/run/cilium\n          type: DirectoryOrCreate\n        name: cilium-run\n      - hostPath:\n          path: /var/run/netns\n          type: DirectoryOrCreate\n        name: cilium-netns\n      - hostPath:\n          path: /sys/fs/bpf\n          type: DirectoryOrCreate\n        name: bpf-maps\n      - hostPath:\n          path: /proc\n          type: Directory\n        name: hostproc\n      - hostPath:\n          path: /sys/fs/cgroup\n          type: DirectoryOrCreate\n        name: cilium-cgroup\n      - hostPath:\n          path: /opt/cni/bin\n          type: DirectoryOrCreate\n        name: cni-path\n      - hostPath:\n          path: /etc/cni/net.d\n          type: DirectoryOrCreate\n        name: etc-cni-netd\n      - hostPath:\n          path: /lib/modules\n        name: lib-modules\n      - hostPath:\n          path: /run/xtables.lock\n          type: FileOrCreate\n        name: xtables-lock\n      - name: clustermesh-secrets\n        projected:\n          defaultMode: 256\n          sources:\n          - secret:\n              name: cilium-clustermesh\n              optional: true\n          - secret:\n              items:\n              - key: tls.key\n                path: common-etcd-client.key\n              - key: tls.crt\n                path: common-etcd-client.crt\n              - key: ca.crt\n                path: common-etcd-client-ca.crt\n              name: clustermesh-apiserver-remote-cert\n              optional: true\n          - secret:\n              items:\n              - key: tls.key\n                path: local-etcd-client.key\n              - key: tls.crt\n                path: local-etcd-client.crt\n              - key: ca.crt\n                path: local-etcd-client-ca.crt\n              name: clustermesh-apiserver-local-cert\n              optional: true\n      - hostPath:\n          path: /proc/sys/net\n          type: Directory\n        name: host-proc-sys-net\n      - hostPath:\n          path: /proc/sys/kernel\n          type: Directory\n        name: host-proc-sys-kernel\n      - name: hubble-tls\n        projected:\n          defaultMode: 256\n          sources:\n          - secret:\n              items:\n              - key: tls.crt\n                path: server.crt\n              - key: tls.key\n                path: server.key\n              - key: ca.crt\n                path: client-ca.crt\n              name: hubble-server-certs\n              optional: true\n  updateStrategy:\n    rollingUpdate:\n      maxUnavailable: 2\n    type: RollingUpdate\n---\napiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-agent\n    app.kubernetes.io/part-of: cilium\n  name: cilium-agent\n  namespace: kube-system\nspec:\n  endpoints:\n  - honorLabels: true\n    interval: 10s\n    path: /metrics\n    port: metrics\n    relabelings:\n    - action: replace\n      replacement: ${1}\n      sourceLabels:\n      - __meta_kubernetes_pod_node_name\n      targetLabel: node\n  namespaceSelector:\n    matchNames:\n    - kube-system\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: cilium-agent\n  targetLabels:\n  - k8s-app\n---\napiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  annotations:\n    meta.helm.sh/release-name: cilium\n    meta.helm.sh/release-namespace: kube-system\n  labels:\n    app.kubernetes.io/managed-by: Helm\n    app.kubernetes.io/name: cilium-operator\n    app.kubernetes.io/part-of: cilium\n  name: cilium-operator\n  namespace: kube-system\nspec:\n  endpoints:\n  - honorLabels: true\n    interval: 10s\n    path: /metrics\n    port: metrics\n  namespaceSelector:\n    matchNames:\n    - kube-system\n  selector:\n    matchLabels:\n      io.cilium/app: operator\n      name: cilium-operator\n  targetLabels:\n  - io.cilium/app\n"
  },
  {
    "path": "talos/integrations/cilium/kustomization.yaml",
    "content": "---\n# yaml-language-server: $schema=https://json.schemastore.org/kustomization\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nhelmCharts:\n  - name: cilium\n    includeCRDs: true\n    releaseName: cilium\n    namespace: kube-system\n    valuesFile: ../../../kubernetes/apps/base/kube-system/cilium/app/values.yaml\n    version: 1.19.4\n    repo: https://helm.cilium.io/\n\n# REQUIRED: Use transformers to avoid creating the labels & annotations on all references rather than only metadata/annotations or metadata/labels respectively\ntransformers:\n  - transformers.yaml\n"
  },
  {
    "path": "talos/integrations/cilium/transformers.yaml",
    "content": "---\napiVersion: builtin\nkind: LabelTransformer\nmetadata:\n  name: labels\nlabels:\n  app.kubernetes.io/managed-by: Helm\nfieldSpecs:\n  - path: metadata/labels\n    create: true\n---\napiVersion: builtin\nkind: AnnotationsTransformer\nmetadata:\n  name: annotations\nannotations:\n  meta.helm.sh/release-name: cilium\n  meta.helm.sh/release-namespace: kube-system\nfieldSpecs:\n  - path: metadata/annotations\n    create: true\n"
  },
  {
    "path": "talos/patches/iscsi.yaml",
    "content": "# https://www.talos.dev/v1.9/kubernetes-guides/configuration/replicated-local-storage-with-openebs/\nmachine:\n  sysctls:\n    vm.nr_hugepages: \"1024\"\n  nodeLabels:\n    openebs.io/engine: mayastor\n  kubelet:\n    extraMounts:\n      - destination: /var/openebs/local\n        type: bind\n        source: /var/openebs/local\n        options:\n          - rbind\n          - rshared\n          - rw\n"
  },
  {
    "path": "talos/patches/metric-server.yaml",
    "content": "# https://www.talos.dev/v1.9/kubernetes-guides/configuration/deploy-metrics-server/\n- op: add\n  path: /machine/kubelet/extraArgs\n  value:\n    rotate-server-certificates: true\n"
  },
  {
    "path": "talos/patches/metrics.yaml",
    "content": "# https://www.talos.dev/v1.9/talos-guides/configuration/containerd/#exposing-metrics\nmachine:\n  files:\n    - content: |\n        [metrics]\n          address = \"0.0.0.0:11234\"\n      path: /etc/cri/conf.d/20-customization.part\n      op: create\n"
  },
  {
    "path": "terraform/gcp/README.md",
    "content": "# Cloud Infrastructure\n\n## Existing Project\n\nUse [terraformer](https://github.com/GoogleCloudPlatform/terraformer) to import existing cloud resources that have been created into TF files.\n\nGCP Example:\n\n```bash\nterraformer import google --resources=gcs,forwardingRules,httpHealthChecks --connect=true --regions=europe-west1,europe-west4 --projects=aaa,fff\n```\n\n## Tips\n\nConsider terraform repository structure [best practices](https://www.terraform-best-practices.com/code-structure)\n"
  },
  {
    "path": "terraform/gcp/_backend.tf",
    "content": "terraform {\n  backend \"gcs\" {\n    bucket = \"raspbernetes-gitops-terraform-state\"\n    prefix = \"terraform/state\"\n  }\n}\n"
  },
  {
    "path": "terraform/gcp/_provider.tf",
    "content": "provider \"google\" {\n  project = var.project_id\n  region  = var.region\n}\n"
  },
  {
    "path": "terraform/gcp/install.sh",
    "content": "#!/bin/bash\nset -euo pipefail\n\n# Notes:\n# - Billing must be activated for the project\n# - Post install \"terraform init\" must be executed to configure against the remote state in GCS\n\n# TODO: Reuse variables for PROJECT_ID to avoid users having to set these in multile locations\n# TODO: Create an uninstall script to remove these resources that are not managed via Terraform\n# TODO: Make script idemopotent so it can be re-run without error\n# TODO: QUOTAS default for IN_USE_ADDRESSES is 8 and needs to be 9\n#   Error: error creating NodePool: googleapi: Error 403: Insufficient regional quota to satisfy request: resource \"IN_USE_ADDRESSES\": request requires '9.0' and is short '1.0'. project has a quota of '8.0' with '8.0' available. View and manage quotas at https://console.cloud.google.com/iam-admin/quotas?usage=USED&project=raspbernetes., forbidden\n\nexport TF_VAR_PROJ_ID=\"${TF_VAR_PROJ_ID:-raspbernetes}\"\nexport TF_CREDS=~/.config/gcloud/${TF_VAR_PROJ_ID}-terraform-admin.json\n\n# Create the service account in the Terraform admin project and download the JSON credentials\ngcloud iam service-accounts create terraform \\\n  --display-name \"Terraform admin account\"\n\ngcloud iam service-accounts keys create \"${TF_CREDS}\" \\\n  --iam-account \"terraform@${TF_VAR_PROJ_ID}.iam.gserviceaccount.com\"\n\n# Grant the service account permission to view the Admin Project and manage Cloud Storage\ngcloud projects add-iam-policy-binding \"${TF_VAR_PROJ_ID}\" \\\n  --member \"serviceAccount:terraform@${TF_VAR_PROJ_ID}.iam.gserviceaccount.com\" \\\n  --role roles/owner\n\ngcloud projects add-iam-policy-binding \"${TF_VAR_PROJ_ID}\" \\\n  --member \"serviceAccount:terraform@${TF_VAR_PROJ_ID}.iam.gserviceaccount.com\" \\\n  --role roles/storage.admin\n\n# Any actions that Terraform performs require that the API be enabled to do so\ngcloud services enable cloudresourcemanager.googleapis.com\ngcloud services enable cloudbilling.googleapis.com\ngcloud services enable iam.googleapis.com\ngcloud services enable compute.googleapis.com\ngcloud services enable serviceusage.googleapis.com\ngcloud services enable container.googleapis.com\n\n# Create the remote backend bucket in Cloud Storage and the backend.tf file for storage of the terraform.tfstate file\ngsutil mb -p \"${TF_VAR_PROJ_ID}\" \"gs://${TF_VAR_PROJ_ID}-gitops-terraform-state\"\n\n# TODO: Make sure backend.tf is located under the infrastructure/ directory\ncat > _backend.tf << EOF\nterraform {\n  backend \"gcs\" {\n    bucket  = \"${TF_VAR_PROJ_ID}-gitops-terraform-state\"\n    prefix  = \"terraform/state\"\n  }\n}\nEOF\n\n# Enable versioning for the remote bucket\ngsutil versioning set on \"gs://${TF_VAR_PROJ_ID}-gitops-terraform-state\"\n\n# Configure your environment for the Google Cloud Terraform provider\nexport GOOGLE_APPLICATION_CREDENTIALS=${TF_CREDS}\nexport GOOGLE_PROJECT=${TF_VAR_PROJ_ID}\n"
  },
  {
    "path": "terraform/gcp/sops.tf",
    "content": "locals {\n  sops_permissions = [\n    \"cloudkms.cryptoKeys.list\",\n    \"cloudkms.cryptoKeys.get\",\n    \"cloudkms.cryptoKeyVersions.get\",\n    \"cloudkms.cryptoKeyVersions.list\",\n    \"cloudkms.cryptoKeyVersions.useToDecrypt\",\n    \"cloudkms.cryptoKeyVersions.useToEncrypt\",\n    \"cloudkms.cryptoKeyVersions.viewPublicKey\",\n    \"cloudkms.keyRings.get\",\n    \"cloudkms.keyRings.list\",\n    \"resourcemanager.projects.get\"\n  ]\n}\n\nresource \"google_kms_key_ring\" \"sops\" {\n  name     = \"sops\"\n  location = \"global\"\n}\n\nresource \"google_kms_crypto_key\" \"sops\" {\n  name     = \"sops-key\"\n  key_ring = google_kms_key_ring.sops.id\n  purpose  = \"ENCRYPT_DECRYPT\"\n  lifecycle {\n    prevent_destroy = true\n  }\n}\n\nresource \"google_project_iam_custom_role\" \"sops\" {\n  role_id     = \"sops\"\n  title       = \"SOPS Role\"\n  description = \"This role grants all required SOPS permissions\"\n  permissions = local.sops_permissions\n}\n\n# Approved list of GCP users with the ability to encrypt/decrypt project secret\nresource \"google_project_iam_binding\" \"sops\" {\n  project = var.project_id\n  role    = \"projects/raspbernetes/roles/${google_project_iam_custom_role.sops.role_id}\"\n  members = [\n    \"user:saurabh.c.pandit@gmail.com\",\n  ]\n}\n"
  },
  {
    "path": "terraform/gcp/thanos.tf",
    "content": "locals {\n  thanos_permissions = [\n    \"compute.snapshots.create\",\n    \"compute.snapshots.delete\",\n    \"compute.snapshots.get\",\n    \"compute.snapshots.list\",\n    \"compute.snapshots.useReadOnly\",\n    \"compute.zones.get\",\n    \"compute.zones.list\",\n    \"resourcemanager.projects.get\",\n    \"storage.objects.create\",\n    \"storage.objects.delete\",\n    \"storage.objects.get\",\n    \"storage.objects.getIamPolicy\",\n    \"storage.objects.list\",\n    \"storage.objects.setIamPolicy\",\n    \"storage.objects.update\"\n  ]\n}\n\nresource \"google_service_account\" \"thanos\" {\n  account_id   = \"thanos\"\n  display_name = \"Service account for Thanos\"\n}\n\nresource \"google_project_iam_custom_role\" \"thanos\" {\n  role_id     = \"thanos\"\n  title       = \"Thanos Role\"\n  description = \"This role grants all required Thanos permissions\"\n  permissions = local.thanos_permissions\n}\n\nresource \"google_project_iam_binding\" \"thanos\" {\n  project = var.project_id\n  role    = google_project_iam_custom_role.thanos.name\n  members = [\n    \"serviceAccount:${google_service_account.thanos.email}\",\n  ]\n}\n\nresource \"google_storage_bucket\" \"thanos\" {\n  default_event_based_hold = \"false\"\n  force_destroy            = \"false\"\n  location                 = \"ASIA\"\n  name                     = \"thanos-raspbernetes-storage\"\n  project                  = \"raspbernetes\"\n  requester_pays           = \"false\"\n  storage_class            = \"STANDARD\"\n}\n"
  },
  {
    "path": "terraform/gcp/variables.tf",
    "content": "variable \"project_id\" {\n  description = \"(OPTIONAL) The GCP project ID to use for the cluster. (default: raspbernetes)\"\n  default     = \"raspbernetes\"\n  type        = string\n}\n\nvariable \"region\" {\n  description = \"(OPTIONAL) The GCP region to use for the cluster. (default: us-central1)\"\n  default     = \"us-central1\"\n  type        = string\n}\n"
  },
  {
    "path": "terraform/gcp/velero.tf",
    "content": "locals {\n  velero_permissions = [\n    \"compute.snapshots.create\",\n    \"compute.snapshots.delete\",\n    \"compute.snapshots.get\",\n    \"compute.snapshots.list\",\n    \"compute.snapshots.useReadOnly\",\n    \"compute.zones.get\",\n    \"compute.zones.list\",\n    \"resourcemanager.projects.get\",\n    \"storage.objects.create\",\n    \"storage.objects.delete\",\n    \"storage.objects.get\",\n    \"storage.objects.getIamPolicy\",\n    \"storage.objects.list\",\n    \"storage.objects.setIamPolicy\",\n    \"storage.objects.update\"\n  ]\n}\n\nresource \"google_service_account\" \"velero\" {\n  account_id   = \"velero\"\n  display_name = \"Service account for Velero\"\n}\n\nresource \"google_project_iam_custom_role\" \"velero\" {\n  role_id     = \"velero\"\n  title       = \"Velero Role\"\n  description = \"This role grants all required Velero permissions\"\n  permissions = local.velero_permissions\n}\n\nresource \"google_project_iam_binding\" \"velero\" {\n  project = var.project_id\n  role    = google_project_iam_custom_role.velero.name\n  members = [\n    \"serviceAccount:${google_service_account.velero.email}\",\n  ]\n}\n\nresource \"google_storage_bucket_iam_binding\" \"binding\" {\n  bucket = google_storage_bucket.openebs.name\n  role   = \"projects/raspbernetes/roles/${google_project_iam_custom_role.velero.role_id}\"\n  members = [\n    \"serviceAccount:${google_service_account.velero.email}\",\n  ]\n}\n\nresource \"google_storage_bucket\" \"velero\" {\n  default_event_based_hold = \"false\"\n  force_destroy            = \"false\"\n  location                 = \"US\"\n  name                     = \"raspbernetes-velero-backups\"\n  project                  = \"raspbernetes\"\n  requester_pays           = \"false\"\n  storage_class            = \"STANDARD\"\n}\n\nresource \"google_storage_bucket\" \"openebs\" {\n  default_event_based_hold = \"false\"\n  force_destroy            = \"false\"\n  location                 = \"US\"\n  name                     = \"raspbernetes-openebs-backups\"\n  project                  = \"raspbernetes\"\n  requester_pays           = \"false\"\n  storage_class            = \"STANDARD\"\n}\n"
  },
  {
    "path": "wrangler.toml",
    "content": "name = \"k8s-gitops\"\ncompatibility_date = \"2026-02-23\"\n\n[assets]\ndirectory = \"./docs\"\n"
  }
]