├── .python-version ├── kubernetes ├── security │ ├── readme.md │ └── policies │ │ └── vap │ │ ├── tests │ │ ├── namespace.yaml │ │ ├── kustomization.yaml │ │ └── job-vap-test.yaml │ │ ├── quotas │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ ├── deletionProtection │ │ ├── kustomization.yaml │ │ ├── restrict-namespace-delete.yaml │ │ └── restrict-educational-delete.yaml │ │ └── hostmount │ │ ├── kustomization.yaml │ │ ├── deny-root-hostmount-pods.yaml │ │ ├── deny-root-hostmount-jobs.yaml │ │ ├── deny-root-hostmount-cronjobs.yaml │ │ ├── deny-root-hostmount-apps.yaml │ │ └── bindings.yaml ├── core │ ├── monitoring │ │ ├── kustomization.yaml │ │ ├── values.yaml │ │ └── values.kps.yaml │ ├── istio-system │ │ ├── cni.values.yaml │ │ ├── istiod.values.yaml │ │ ├── ztunnel.values.yaml │ │ └── istio-base.values.yaml │ ├── argocd │ │ ├── namespace.yaml │ │ ├── repo │ │ │ ├── kustomization.yaml │ │ │ ├── envoy-gateway.yaml │ │ │ ├── home-operations-charts.yaml │ │ │ └── snapshot-controller.yaml │ │ ├── kustomization.yaml │ │ ├── argo-appproject.yaml │ │ ├── app-of-apps.yaml │ │ ├── external-dns.yaml │ │ ├── readme.md │ │ ├── tlsroute.yaml │ │ ├── oidc-secret.yaml │ │ └── values.yaml │ ├── forgejo │ │ ├── namespace.yaml │ │ ├── kustomization.yaml │ │ ├── db-superuser.yaml │ │ ├── secret.meilisearch.yaml │ │ └── secret.forgejo.yaml │ ├── harbor │ │ ├── namespace.yaml │ │ ├── networking │ │ │ ├── kustomization.yaml │ │ │ ├── external-name.yaml │ │ │ └── httproute.yaml │ │ ├── certs │ │ │ ├── kustomization.yaml │ │ │ ├── harbor-token-ca.yaml │ │ │ ├── harbor-internal-ca.yaml │ │ │ └── harbor-internal-certs.yaml │ │ └── kustomization.yaml │ ├── openbao │ │ ├── namespace.yaml │ │ ├── kustomization.yaml │ │ ├── readme.md │ │ └── cert.yaml │ ├── volsync │ │ ├── snapshot-controller.values.yaml │ │ └── volsync.values.yaml │ ├── cert-manager │ │ ├── values.cert-manager-webhook-pdns.yaml │ │ ├── self-signed-issuer.yaml │ │ ├── values.cert-manager.yaml │ │ ├── kustomization.yaml │ │ ├── readme.md │ │ └── certbot.yaml │ ├── runtimes │ │ └── nvidia.yaml │ ├── database │ │ ├── namespace.yaml │ │ ├── kustomization.yaml │ │ ├── readme.md │ │ ├── database.yaml │ │ └── secret.database.yaml │ ├── powerdns │ │ ├── namespace.yaml │ │ ├── unifi-dns-nat.png │ │ ├── unifi-dns-settings.png │ │ ├── kustomization.yaml │ │ ├── db-superuser.yaml │ │ ├── db-creds.yaml │ │ ├── as-secret.yaml │ │ └── readme.md │ ├── rook-ceph │ │ ├── kustomization.yaml │ │ ├── operator.values.yaml │ │ ├── ceph-retain-sc.yaml │ │ └── readme.md │ ├── keycloak │ │ ├── namespace.yaml │ │ ├── kustomization.yaml │ │ ├── db-superuser.yaml │ │ ├── keycloak-superuser-secret.yaml │ │ └── db-creds.yaml │ ├── rook-ceph-external │ │ ├── kustomization.yaml │ │ ├── cephfs-retain-sc.yaml │ │ ├── cluster.values.yaml │ │ ├── ceph-rbd-retain-sc.yaml │ │ ├── readme.md │ │ └── values.yaml │ ├── gateway-api │ │ ├── kustomization.yaml │ │ ├── cert-wildcard.yaml │ │ └── gateway.yaml │ ├── sealed-secrets │ │ └── values.yaml │ ├── gatus │ │ ├── kustomization.yaml │ │ └── resources │ │ │ └── config.yaml │ └── kube-system │ │ ├── cilium │ │ ├── bgp │ │ │ ├── kustomization.yaml │ │ │ ├── CiliumLoadBalancerIPPool.yaml │ │ │ ├── CiliumBGPPeerConfig.yaml │ │ │ ├── CiliumL2AnnouncementPolicy.yaml │ │ │ ├── CiliumBGPAdvertisement.yaml │ │ │ └── CiliumBGPClusterConfig.yaml │ │ └── values.yaml │ │ ├── metrics-server │ │ └── values.yaml │ │ ├── reflector │ │ └── readme.md │ │ ├── coredns │ │ └── values.yaml │ │ └── external-dns │ │ └── values.yaml ├── services │ ├── jupyter │ │ ├── namespace.yaml │ │ ├── kustomization.yaml │ │ ├── readme.md │ │ ├── cilium-netpol.yaml │ │ ├── ingress.yaml │ │ └── values.yaml │ ├── palworld │ │ ├── namespace.yaml │ │ ├── kustomization.yaml │ │ └── secrets.yaml │ ├── open-webui │ │ ├── namespace.yaml │ │ ├── db-creds.yaml │ │ ├── db-superuser.yaml │ │ ├── kustomization.yaml │ │ └── oidc-secret.yaml │ ├── github-action-runners │ │ ├── runners │ │ │ ├── kustomization.yaml │ │ │ ├── service-account.yaml │ │ │ ├── rbac.yaml │ │ │ ├── values.yaml │ │ │ ├── runner.yaml │ │ │ └── gh-app-creds.yaml │ │ └── controller │ │ │ └── values.yaml │ ├── iperf3 │ │ ├── readme.md │ │ └── values.yaml │ ├── librechat │ │ ├── kustomization.yaml │ │ ├── readme.md │ │ └── embeddings-ollama.values.yaml │ ├── playwright │ │ └── values.yaml │ ├── nvdp │ │ └── values.yaml │ ├── docling │ │ └── values.yaml │ ├── tabbyml │ │ └── values.yaml │ └── n8n │ │ └── values.yaml ├── projects │ ├── storm-paragraph │ │ ├── namespace.yaml │ │ ├── quotas │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ ├── app-of-apps.yaml │ │ ├── appproject.yaml │ │ └── rbac.yaml │ ├── danger-million │ │ ├── quotas │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ ├── namespace.yaml │ │ ├── app-of-apps.yaml │ │ ├── values.yaml │ │ ├── appproject.yaml │ │ └── rbac.yaml │ ├── steel-ambiguity │ │ ├── quotas │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ ├── namespace.yaml │ │ ├── app-of-apps.yaml │ │ ├── appproject.yaml │ │ └── rbac.yaml │ ├── wander-winter │ │ ├── quotas │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ ├── namespace.yaml │ │ ├── app-of-apps.yaml │ │ ├── appproject.yaml │ │ └── rbac.yaml │ ├── kustomization.yaml │ └── quotas │ │ ├── kustomization.yaml │ │ ├── storage.yaml │ │ └── resources.yaml ├── applications │ ├── security-policies.yaml │ ├── gateway-api.yaml │ ├── cnpg.yaml │ ├── education.yaml │ ├── reflector.yaml │ ├── istio-ingress.yaml │ ├── iperf3.yaml │ ├── n8n.yaml │ ├── comfyui.yaml │ ├── coredns.yaml │ ├── docling.yaml │ ├── k8s-mcp.yaml │ ├── disabled │ │ ├── tabbyml.yaml │ │ └── palworld.yaml │ ├── external-dns.yaml │ ├── metrics-server.yaml │ ├── sealed-secrets.yaml │ ├── harbor.yaml │ ├── monitoring.yaml │ ├── cilium.yaml │ ├── keycloak.yaml │ ├── powerdns.yaml │ ├── gatus.yaml │ ├── forgejo.yaml │ ├── ollama.yaml │ ├── nvidia.yaml │ ├── volsync.yaml │ ├── rook-ceph.yaml │ ├── cert-manager.yaml │ ├── gh-runners.yaml │ └── istio.yaml └── readme.md ├── keys ├── ca.key.enc ├── sealed-secret.key.enc ├── ca.crt ├── gen-aws-iam-ra.sh └── sealed-secret.crt ├── infrastructure ├── images │ ├── pmx1-network.png │ ├── pmx5-network.png │ ├── pmx6-network.png │ ├── pmx7-network.png │ ├── pmx8-network.png │ ├── talos-normal.png │ └── talos-nvidia.png └── clusterconfig │ └── .gitignore ├── .gitignore ├── .vscode └── settings.json ├── pyproject.toml ├── .github ├── scripts │ ├── functions.sh │ └── helm-argo-add.sh ├── scratchpad.md ├── workflows │ ├── opencode.yml │ └── kwok-validation.yaml └── renovate.json5 ├── .sops.yaml ├── .pre-commit-config.yaml ├── opencode.json ├── unifi └── bgp.conf ├── scripts └── sealed-secrets-generate.sh └── taskfile.yaml /.python-version: -------------------------------------------------------------------------------- 1 | 3.13 2 | -------------------------------------------------------------------------------- /kubernetes/security/readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes/core/monitoring/kustomization.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kubernetes/core/istio-system/cni.values.yaml: -------------------------------------------------------------------------------- 1 | profile: ambient 2 | -------------------------------------------------------------------------------- /kubernetes/core/istio-system/istiod.values.yaml: -------------------------------------------------------------------------------- 1 | profile: ambient 2 | -------------------------------------------------------------------------------- /kubernetes/core/istio-system/ztunnel.values.yaml: -------------------------------------------------------------------------------- 1 | profile: ambient 2 | -------------------------------------------------------------------------------- /keys/ca.key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/keys/ca.key.enc -------------------------------------------------------------------------------- /kubernetes/core/argocd/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: argocd 5 | -------------------------------------------------------------------------------- /kubernetes/core/forgejo/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: forgejo 5 | -------------------------------------------------------------------------------- /kubernetes/core/harbor/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: harbor 5 | -------------------------------------------------------------------------------- /kubernetes/core/harbor/networking/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - httproute.yaml 3 | - external-name.yaml 4 | -------------------------------------------------------------------------------- /kubernetes/core/openbao/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: openbao 5 | -------------------------------------------------------------------------------- /kubernetes/core/volsync/snapshot-controller.values.yaml: -------------------------------------------------------------------------------- 1 | controller: 2 | serviceMonitor: 3 | create: false -------------------------------------------------------------------------------- /kubernetes/core/cert-manager/values.cert-manager-webhook-pdns.yaml: -------------------------------------------------------------------------------- 1 | groupName: capi-core.homelab.danmanners.com 2 | -------------------------------------------------------------------------------- /kubernetes/services/jupyter/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: jupyter 5 | -------------------------------------------------------------------------------- /kubernetes/services/palworld/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: palworld 5 | -------------------------------------------------------------------------------- /kubernetes/services/open-webui/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: aiml 6 | -------------------------------------------------------------------------------- /keys/sealed-secret.key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/keys/sealed-secret.key.enc -------------------------------------------------------------------------------- /infrastructure/images/pmx1-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/infrastructure/images/pmx1-network.png -------------------------------------------------------------------------------- /infrastructure/images/pmx5-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/infrastructure/images/pmx5-network.png -------------------------------------------------------------------------------- /infrastructure/images/pmx6-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/infrastructure/images/pmx6-network.png -------------------------------------------------------------------------------- /infrastructure/images/pmx7-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/infrastructure/images/pmx7-network.png -------------------------------------------------------------------------------- /infrastructure/images/pmx8-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/infrastructure/images/pmx8-network.png -------------------------------------------------------------------------------- /infrastructure/images/talos-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/infrastructure/images/talos-normal.png -------------------------------------------------------------------------------- /infrastructure/images/talos-nvidia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/infrastructure/images/talos-nvidia.png -------------------------------------------------------------------------------- /kubernetes/core/harbor/certs/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - harbor-internal-ca.yaml 3 | - harbor-internal-certs.yaml 4 | - harbor-token-ca.yaml 5 | -------------------------------------------------------------------------------- /kubernetes/core/runtimes/nvidia.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: node.k8s.io/v1 3 | kind: RuntimeClass 4 | metadata: 5 | name: nvidia 6 | handler: nvidia 7 | -------------------------------------------------------------------------------- /kubernetes/services/palworld/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: palworld 2 | resources: 3 | - aws-secrets.yaml 4 | - namespace.yaml 5 | - secrets.yaml 6 | -------------------------------------------------------------------------------- /kubernetes/core/database/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: database 5 | labels: 6 | security: restricted 7 | -------------------------------------------------------------------------------- /kubernetes/core/harbor/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: harbor 2 | resources: 3 | - certs 4 | - networking 5 | - namespace.yaml 6 | - secret.yaml 7 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: powerdns 5 | labels: 6 | security: restricted 7 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/unifi-dns-nat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/kubernetes/core/powerdns/unifi-dns-nat.png -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ceph-retain-sc.yaml 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files to ignore in the repository 2 | *.pem 3 | *.key 4 | age.txt 5 | *.log 6 | .DS_Store 7 | *.swp 8 | *.tgz 9 | 10 | *.venv/ 11 | history/ 12 | -------------------------------------------------------------------------------- /kubernetes/core/keycloak/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: keycloak 6 | labels: 7 | security: restricted 8 | -------------------------------------------------------------------------------- /kubernetes/services/github-action-runners/runners/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - gh-app-creds.yaml 3 | - rbac.yaml 4 | - runner.yaml 5 | - service-account.yaml 6 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/unifi-dns-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoodMannersHosting/home-enterprise-labops/HEAD/kubernetes/core/powerdns/unifi-dns-settings.png -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/tests/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: testing 5 | labels: 6 | security: restricted 7 | -------------------------------------------------------------------------------- /kubernetes/core/cert-manager/self-signed-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: selfsigned-issuer 5 | spec: 6 | selfSigned: {} 7 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/quotas/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - resourcequota.yaml 7 | -------------------------------------------------------------------------------- /kubernetes/core/forgejo/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: forgejo 2 | resources: 3 | - namespace.yaml 4 | - db-superuser.yaml 5 | - secret.forgejo.yaml 6 | - secret.meilisearch.yaml 7 | -------------------------------------------------------------------------------- /kubernetes/core/openbao/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: openbao 4 | 5 | resources: 6 | - namespace.yaml 7 | - cert.yaml 8 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/tests/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - namespace.yaml 6 | - job-vap-test.yaml 7 | -------------------------------------------------------------------------------- /kubernetes/projects/storm-paragraph/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: storm-paragraph 5 | labels: 6 | security: restricted 7 | educational: "true" 8 | -------------------------------------------------------------------------------- /kubernetes/services/jupyter/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - cilium-netpol.yaml 6 | - ingress.yaml 7 | - namespace.yaml 8 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph-external/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - cephfs-retain-sc.yaml 6 | - ceph-block-retain-sc.yaml 7 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/repo/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - envoy-gateway.yaml 3 | - helo-education-repo.yaml 4 | - helo-repo.yaml 5 | - home-operations-charts.yaml 6 | - snapshot-controller.yaml 7 | -------------------------------------------------------------------------------- /kubernetes/projects/danger-million/quotas/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | namespace: danger-million 5 | 6 | resources: 7 | - ../../quotas 8 | -------------------------------------------------------------------------------- /kubernetes/projects/steel-ambiguity/quotas/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | namespace: steel-ambiguity 5 | 6 | resources: 7 | - ../../quotas 8 | -------------------------------------------------------------------------------- /kubernetes/projects/storm-paragraph/quotas/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | namespace: storm-paragraph 5 | 6 | resources: 7 | - ../../quotas 8 | -------------------------------------------------------------------------------- /kubernetes/projects/wander-winter/quotas/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | namespace: wander-winter 5 | 6 | resources: 7 | - ../../quotas 8 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - hostmount 7 | - quotas 8 | - deletionProtection 9 | -------------------------------------------------------------------------------- /kubernetes/services/jupyter/readme.md: -------------------------------------------------------------------------------- 1 | # Kickoff 2 | 3 | ```bash 4 | helm upgrade --install jupyter jupyterhub/jupyterhub --version 4.2.0 5 | --values kubernetes/services/jupyter/values.yaml -n aiml 6 | ``` 7 | -------------------------------------------------------------------------------- /kubernetes/core/gateway-api/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - gateway.yaml 3 | - cert-wildcard.yaml 4 | - https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental-install.yaml 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "sarif-viewer.connectToGithubCodeScanning": "off", 3 | "workbench.colorCustomizations": { 4 | "activityBar.background": "#242424", 5 | "activityBar.foreground": "#f6ff00" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /kubernetes/core/cert-manager/values.cert-manager.yaml: -------------------------------------------------------------------------------- 1 | extraArgs: 2 | - --dns01-recursive-nameservers-only 3 | - --dns01-recursive-nameservers=172.31.0.11:53 # The IP **MUST** Match the BGP IP Address for the DNS Server 4 | -------------------------------------------------------------------------------- /kubernetes/core/database/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: database 4 | 5 | resources: 6 | - database.yaml 7 | - namespace.yaml 8 | - secret.database.yaml 9 | -------------------------------------------------------------------------------- /kubernetes/core/sealed-secrets/values.yaml: -------------------------------------------------------------------------------- 1 | createController: true 2 | serviceAccount: 3 | create: true 4 | resources: 5 | requests: 6 | cpu: 25m 7 | memory: 128Mi 8 | limits: 9 | cpu: 100m 10 | memory: 256Mi 11 | -------------------------------------------------------------------------------- /kubernetes/projects/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - danger-million 7 | - storm-paragraph 8 | - wander-winter 9 | - steel-ambiguity 10 | -------------------------------------------------------------------------------- /kubernetes/core/keycloak/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - db-creds.yaml 6 | - db-superuser.yaml 7 | - keycloak-superuser-secret.yaml 8 | - namespace.yaml 9 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/deletionProtection/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - restrict-educational-delete.yaml 7 | - restrict-namespace-delete.yaml 8 | -------------------------------------------------------------------------------- /kubernetes/core/forgejo/db-superuser.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: db-superuser 5 | namespace: forgejo 6 | annotations: 7 | reflector.v1.k8s.emberstack.com/reflects: database/database-superuser 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /kubernetes/core/keycloak/db-superuser.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: db-superuser 5 | namespace: keycloak 6 | annotations: 7 | reflector.v1.k8s.emberstack.com/reflects: database/database-superuser 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: powerdns 4 | 5 | resources: 6 | - as-secret.yaml 7 | - db-creds.yaml 8 | - db-superuser.yaml 9 | - namespace.yaml 10 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/db-superuser.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: powerdns-superuser 5 | namespace: powerdns 6 | annotations: 7 | reflector.v1.k8s.emberstack.com/reflects: database/database-superuser 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /kubernetes/services/open-webui/db-creds.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | type: Opaque 5 | metadata: 6 | name: ollama-db-creds 7 | namespace: aiml 8 | stringData: 9 | POSTGRES_USER_PASSWORD: 657429c7&1d97&4bdc&b2c6&3809a3bd68a0 10 | -------------------------------------------------------------------------------- /kubernetes/services/open-webui/db-superuser.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: db-superuser 5 | namespace: aiml 6 | annotations: 7 | reflector.v1.k8s.emberstack.com/reflects: database/database-superuser 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /kubernetes/services/open-webui/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: aiml 4 | 5 | resources: 6 | - db-creds.yaml 7 | - db-superuser.yaml 8 | - namespace.yaml 9 | - oidc-secret.yaml 10 | -------------------------------------------------------------------------------- /kubernetes/projects/wander-winter/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - app-of-apps.yaml 7 | - appproject.yaml 8 | - namespace.yaml 9 | - quotas 10 | - rbac.yaml 11 | -------------------------------------------------------------------------------- /kubernetes/projects/danger-million/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - app-of-apps.yaml 7 | - appproject.yaml 8 | - namespace.yaml 9 | - quotas 10 | - rbac.yaml 11 | -------------------------------------------------------------------------------- /kubernetes/projects/steel-ambiguity/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - app-of-apps.yaml 7 | - appproject.yaml 8 | - namespace.yaml 9 | - quotas 10 | - rbac.yaml 11 | -------------------------------------------------------------------------------- /kubernetes/projects/storm-paragraph/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - app-of-apps.yaml 7 | - appproject.yaml 8 | - namespace.yaml 9 | - quotas 10 | - rbac.yaml 11 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "home-enterprise-labops" 3 | version = "0.1.0" 4 | description = "HELO: Test Big Ideas in Small Spaces." 5 | readme = ".github/readme.md" 6 | requires-python = ">=3.13" 7 | dependencies = [ 8 | "pre-commit>=4.2.0", 9 | ] 10 | -------------------------------------------------------------------------------- /kubernetes/core/cert-manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - certbot.yaml 6 | - self-signed-issuer.yaml 7 | - https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.crds.yaml 8 | -------------------------------------------------------------------------------- /kubernetes/projects/quotas/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | labels: 5 | - includeSelectors: true 6 | pairs: 7 | educational: "true" 8 | 9 | resources: 10 | - resources.yaml 11 | - storage.yaml 12 | -------------------------------------------------------------------------------- /kubernetes/core/istio-system/istio-base.values.yaml: -------------------------------------------------------------------------------- 1 | meshConfig: 2 | defaultConfig: 3 | proxyMetadata: 4 | ISTIO_META_ENABLE_HBONE: "true" 5 | global: 6 | variant: distroless 7 | pilot: 8 | env: 9 | PILOT_ENABLE_AMBIENT: "true" 10 | cni: 11 | ambient: 12 | enabled: true 13 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/repo/envoy-gateway.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: envoy-gateway-oci 5 | labels: 6 | argocd.argoproj.io/secret-type: repository 7 | stringData: 8 | url: docker.io/envoyproxy 9 | name: envoy-gateway 10 | type: helm 11 | enableOCI: "true" 12 | -------------------------------------------------------------------------------- /kubernetes/core/gatus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: gatus 4 | 5 | configMapGenerator: 6 | - name: gatus-configmap 7 | files: 8 | - config.yaml=./resources/config.yaml 9 | generatorOptions: 10 | disableNameSuffixHash: true 11 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/cilium/bgp/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - CiliumBGPAdvertisement.yaml 6 | - CiliumBGPClusterConfig.yaml 7 | - CiliumBGPPeerConfig.yaml 8 | - CiliumL2AnnouncementPolicy.yaml 9 | - CiliumLoadBalancerIPPool.yaml 10 | -------------------------------------------------------------------------------- /kubernetes/core/monitoring/values.yaml: -------------------------------------------------------------------------------- 1 | prometheus: 2 | prometheusSpec: 3 | storageSpec: 4 | volumeClaimTemplate: 5 | spec: 6 | storageClassName: ceph-block-retain 7 | accessModes: ["ReadWriteOnce"] 8 | resources: 9 | requests: 10 | storage: 50Gi 11 | -------------------------------------------------------------------------------- /kubernetes/services/iperf3/readme.md: -------------------------------------------------------------------------------- 1 | # iperf3 Server 2 | 3 | Quick way to run an iperf3 server in Kubernetes for networking tests. 4 | 5 | ```bash 6 | helm template iperf3 --namespace iperf3 \ 7 | bjw-s/app-template --version 4.1.2 \ 8 | --values kubernetes/services/iperf3/values.yaml | \ 9 | kubectl apply -f- 10 | ``` 11 | -------------------------------------------------------------------------------- /kubernetes/core/database/readme.md: -------------------------------------------------------------------------------- 1 | # Install CNPG 2 | 3 | ```bash 4 | helm repo add cnpg https://cloudnative-pg.github.io/charts; helm repo update 5 | 6 | helm upgrade --install cnpg cnpg/cloudnative-pg \ 7 | --namespace database --create-namespace --version 0.24.0 8 | 9 | kubectl apply -k kubernetes/core/database 10 | ``` 11 | -------------------------------------------------------------------------------- /.github/scripts/functions.sh: -------------------------------------------------------------------------------- 1 | # Scrape all namespaces from kubernetes YAML files 2 | function get_namespaces() { 3 | for file in $(find kubernetes/ -name '*.yaml' -type f); do 4 | cat ${file} | yq e 'explode(.)' | 5 | grep 'namespace:' | awk '{print $2}' 6 | done | tr -d '"' | sort | uniq | grep -Ev 'namespace|default|kube-' | xargs 7 | } -------------------------------------------------------------------------------- /kubernetes/core/argocd/repo/home-operations-charts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: home-operations-charts-oci 5 | labels: 6 | argocd.argoproj.io/secret-type: repository 7 | stringData: 8 | url: ghcr.io/home-operations/charts-mirror 9 | name: charts-mirror 10 | type: helm 11 | enableOCI: "true" 12 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/hostmount/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | 5 | resources: 6 | - bindings.yaml 7 | - deny-root-hostmount-apps.yaml 8 | - deny-root-hostmount-cronjobs.yaml 9 | - deny-root-hostmount-jobs.yaml 10 | - deny-root-hostmount-pods.yaml 11 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/repo/snapshot-controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: piraeusdatastore 5 | labels: 6 | argocd.argoproj.io/secret-type: repository 7 | stringData: 8 | url: ghcr.io/piraeusdatastore/helm-charts 9 | name: piraeusdatastore-helm-charts 10 | type: helm 11 | enableOCI: "true" 12 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/metrics-server/values.yaml: -------------------------------------------------------------------------------- 1 | args: 2 | - --secure-port=10250 3 | - --cert-dir=/tmp 4 | - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname 5 | - --kubelet-use-node-status-port 6 | - --metric-resolution=15s 7 | - --kubelet-insecure-tls # TODO: remove this when the TLS certificates are fixed with the Talos config 8 | -------------------------------------------------------------------------------- /kubernetes/projects/danger-million/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.1/namespace.json 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | name: danger-million 7 | labels: 8 | security: restricted 9 | educational: "true" 10 | -------------------------------------------------------------------------------- /kubernetes/projects/wander-winter/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.1/namespace.json 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | name: wander-winter 7 | labels: 8 | security: restricted 9 | educational: "true" 10 | -------------------------------------------------------------------------------- /kubernetes/projects/steel-ambiguity/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.1/namespace.json 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | name: steel-ambiguity 7 | labels: 8 | security: restricted 9 | educational: "true" 10 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - repo 6 | - namespace.yaml 7 | - external-dns.yaml 8 | - oidc-secret.yaml 9 | - tlsroute.yaml 10 | - app-of-apps.yaml 11 | - argo-appproject.yaml 12 | - https://github.com/argoproj/argo-cd/manifests/crds?ref=v3.1.4 13 | -------------------------------------------------------------------------------- /kubernetes/services/librechat/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: aiml 4 | 5 | resources: 6 | - librechat-secrets.yaml 7 | 8 | configMapGenerator: 9 | - name: librechat-config 10 | files: 11 | - librechat.yaml=./librechat.yaml 12 | 13 | generatorOptions: 14 | disableNameSuffixHash: true 15 | -------------------------------------------------------------------------------- /kubernetes/core/harbor/networking/external-name.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: harbor-extname 6 | annotations: 7 | external-dns.alpha.kubernetes.io/hostname: harbor.cloud.danmanners.com 8 | external-dns.alpha.kubernetes.io/ttl: "300" 9 | spec: 10 | type: ExternalName 11 | externalName: unifi-home.homelab.danmanners.com 12 | sessionAffinity: None 13 | -------------------------------------------------------------------------------- /.github/scratchpad.md: -------------------------------------------------------------------------------- 1 | # Scratchpad Notes and bash commands 2 | 3 | ## age encryption of the sealed-secret key 4 | 5 | ```bash 6 | age -i /Users/dan/.config/age/age.txt \ 7 | -e -o keys/sealed-secret.key{.enc,} 8 | ``` 9 | 10 | ## Kubeseal to encrypt secrets 11 | 12 | ```bash 13 | kubeseal --cert keys/sealed-secret.crt \ 14 | -oyaml -{f,w}=kubernetes/capi/capmox/capmox-manager-credentials.yaml 15 | ``` 16 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/cilium/bgp/CiliumLoadBalancerIPPool.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://kubernetes-schemas.ok8.sh/cilium.io/ciliumloadbalancerippool_v2alpha1.json 3 | apiVersion: cilium.io/v2alpha1 4 | kind: CiliumLoadBalancerIPPool 5 | metadata: 6 | name: lb-pool 7 | spec: 8 | allowFirstLastIPs: "Yes" 9 | blocks: 10 | - start: 172.31.0.10 11 | stop: 172.31.1.250 12 | -------------------------------------------------------------------------------- /kubernetes/projects/quotas/storage.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.1/limitrange.json 3 | apiVersion: v1 4 | kind: LimitRange 5 | metadata: 6 | name: educational-storagelimits 7 | spec: 8 | limits: 9 | - type: PersistentVolumeClaim 10 | max: 11 | storage: 8Gi 12 | min: 13 | storage: 1Gi 14 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/cilium/bgp/CiliumBGPPeerConfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://kubernetes-schemas.ok8.sh/cilium.io/ciliumbgppeerconfig_v2alpha1.json 3 | apiVersion: "cilium.io/v2alpha1" 4 | kind: CiliumBGPPeerConfig 5 | metadata: 6 | name: cilium-bgp-peer-config-ipv4 7 | spec: 8 | families: 9 | - afi: ipv4 10 | safi: unicast 11 | advertisements: 12 | matchLabels: 13 | advertise: "bgp" 14 | -------------------------------------------------------------------------------- /.sops.yaml: -------------------------------------------------------------------------------- 1 | creation_rules: 2 | - shamir_threshold: 1 3 | path_regex: .*talsecret\.(yaml|yml)$ 4 | input_type: yaml 5 | encrypted_regex: ^(token|crt|key|id|secret|secretboxEncryptionSecret|ca)$ 6 | mac_only_encrypted: true 7 | key_groups: 8 | - age: 9 | - age1aq9fayk647u8rp7vfl4z4k9drp4mztluumgvm09w2uz36f5exysspkvk7p 10 | - age1986cspgjd7xhdwfwmyplc5jsjk43gewedu7s3sr7gwwhrdp7rgzq6t4ax9 11 | stores: 12 | yaml: 13 | indent: 2 14 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/cilium/bgp/CiliumL2AnnouncementPolicy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://kubernetes-schemas.ok8.sh/cilium.io/ciliuml2announcementpolicy_v2alpha1.json 3 | apiVersion: cilium.io/v2alpha1 4 | kind: CiliumL2AnnouncementPolicy 5 | metadata: 6 | name: l2-policy 7 | spec: 8 | loadBalancerIPs: true 9 | interfaces: [ "^enp.*" ] 10 | nodeSelector: 11 | matchLabels: 12 | kubernetes.io/os: linux 13 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/reflector/readme.md: -------------------------------------------------------------------------------- 1 | # emberstack/kubernetes-reflector 2 | 3 | Installing [emberstack/kubernetes-reflector](https://github.com/emberstack/kubernetes-reflector) in the `kube-system` namespace. 4 | 5 | ```bash 6 | helm repo add emberstack https://emberstack.github.io/helm-charts 7 | helm repo update 8 | 9 | helm upgrade --install reflector \ 10 | --namespace kube-system --version 9.1.21 \ 11 | emberstack/reflector 12 | ``` 13 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: local 3 | hooks: 4 | - id: trufflehog 5 | name: TruffleHog 6 | description: Detect secrets in your data. 7 | entry: |- 8 | bash -c 'trufflehog \ 9 | git file://. \ 10 | --since-commit HEAD \ 11 | --results=unverified,verified,unknown \ 12 | --fail \ 13 | --no-update 14 | ' 15 | language: system 16 | stages: [ "pre-commit", "pre-push" ] 17 | -------------------------------------------------------------------------------- /kubernetes/services/github-action-runners/runners/service-account.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Source: gha-runner-scale-set/templates/no_permission_serviceaccount.yaml 3 | apiVersion: v1 4 | kind: ServiceAccount 5 | metadata: 6 | name: shr-gha-rs-no-permission 7 | namespace: github 8 | labels: 9 | actions.github.com/scale-set-name: shr 10 | actions.github.com/scale-set-namespace: github 11 | finalizers: 12 | - actions.github.com/cleanup-protection 13 | -------------------------------------------------------------------------------- /kubernetes/services/jupyter/cilium-netpol.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "cilium.io/v2" 2 | kind: CiliumNetworkPolicy 3 | metadata: 4 | name: "dev-to-kube-apiserver" 5 | namespace: aiml 6 | spec: 7 | endpointSelector: 8 | # This is necessary to allow the JupyterHub hub to 9 | # communicate with the Kubernetes API server. 10 | matchLabels: 11 | app: jupyterhub 12 | component: hub 13 | egress: 14 | - toEntities: 15 | - kube-apiserver 16 | -------------------------------------------------------------------------------- /kubernetes/core/volsync/volsync.values.yaml: -------------------------------------------------------------------------------- 1 | fullnameOverride: volsync # Required for volsync-perfectra1n fork 2 | image: &image 3 | repository: ghcr.io/perfectra1n/volsync 4 | tag: v0.15.42 5 | kopia: *image 6 | rclone: *image 7 | restic: *image 8 | rsync: *image 9 | rsync-tls: *image 10 | syncthing: *image 11 | manageCRDs: true 12 | metrics: 13 | disableAuth: true 14 | podSecurityContext: 15 | runAsNonRoot: true 16 | runAsUser: 1000 17 | runAsGroup: 1000 -------------------------------------------------------------------------------- /kubernetes/projects/quotas/resources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.34.1/resourcequota.json 3 | apiVersion: v1 4 | kind: ResourceQuota 5 | metadata: 6 | name: educational-quota 7 | spec: 8 | hard: 9 | limits.cpu: "10" 10 | limits.memory: "20Gi" 11 | limits.ephemeral-storage: "20Gi" 12 | limits.nvidia.com/gpu: 0 13 | persistentvolumeclaims: "10" 14 | -------------------------------------------------------------------------------- /infrastructure/clusterconfig/.gitignore: -------------------------------------------------------------------------------- 1 | capi-core-segfault.homelab.danmanners.com.yaml 2 | capi-core-quantumleap.homelab.danmanners.com.yaml 3 | talosconfig 4 | helo-segfault.homelab.danmanners.com.yaml 5 | helo-quantumleap.homelab.danmanners.com.yaml 6 | helo-cachecow.homelab.danmanners.com.yaml 7 | helo-rampage.homelab.danmanners.com.yaml 8 | helo-publicforum.homelab.danmanners.com.yaml 9 | helo-zephyr.homelab.danmanners.com.yaml 10 | helo-stackover.homelab.danmanners.com.yaml 11 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/argo-appproject.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: argocd 5 | namespace: argocd 6 | spec: 7 | description: App of Apps 8 | clusterResourceWhitelist: 9 | - group: "argoproj.io" 10 | kind: "appprojects" 11 | destinations: 12 | - namespace: argocd 13 | server: https://kubernetes.default.svc 14 | sourceRepos: 15 | - "https://github.com/GoodMannersHosting/home-enterprise-labops.git" 16 | -------------------------------------------------------------------------------- /opencode.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://opencode.ai/config.json", 3 | "provider": { 4 | "danollama": { 5 | "npm": "@ai-sdk/openai-compatible", 6 | "name": "danollama", 7 | "options": { 8 | "baseURL": "https://ollama.cloud.danmanners.com/api", 9 | "apiKey": "{env:OLLAMA_API_KEY}" 10 | }, 11 | "models": { 12 | "qwen3:4b": { 13 | "name": "Qwen3" 14 | }, 15 | "qwen3-coder:30b": { 16 | "name": "Qwen3 Coder" 17 | } 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /kubernetes/core/argocd/app-of-apps.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argocd-app-of-apps 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: argocd 9 | server: https://kubernetes.default.svc 10 | project: argocd 11 | sources: 12 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 13 | targetRevision: main 14 | path: kubernetes/applications 15 | directory: {} # recurse: true # We don't want to dive into the disabled directory 16 | -------------------------------------------------------------------------------- /kubernetes/services/github-action-runners/controller/values.yaml: -------------------------------------------------------------------------------- 1 | fullnameOverride: "arc" 2 | replicaCount: 1 3 | 4 | image: 5 | repository: "ghcr.io/actions/gha-runner-scale-set-controller" 6 | pullPolicy: IfNotPresent 7 | 8 | serviceAccount: 9 | create: true 10 | 11 | flags: 12 | logLevel: "debug" 13 | logFormat: "json" 14 | runnerMaxConcurrentReconciles: 4 15 | updateStrategy: "eventual" 16 | excludeLabelPropagationPrefixes: 17 | - "argocd.argoproj.io/instance" 18 | 19 | k8sClientRateLimiterQPS: 20 20 | k8sClientRateLimiterBurst: 30 21 | -------------------------------------------------------------------------------- /kubernetes/projects/wander-winter/app-of-apps.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: wander-winter 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: wander-winter 9 | server: https://kubernetes.default.svc 10 | project: wander-winter 11 | sources: 12 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-education.git 13 | targetRevision: main 14 | path: wander-winter/applications 15 | directory: {} # We don't want to dive into the disabled directory, so recurse will not be set. 16 | -------------------------------------------------------------------------------- /kubernetes/projects/danger-million/app-of-apps.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: danger-million 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: danger-million 9 | server: https://kubernetes.default.svc 10 | project: danger-million 11 | sources: 12 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-education.git 13 | targetRevision: main 14 | path: danger-million/applications 15 | directory: {} # We don't want to dive into the disabled directory, so recurse will not be set. 16 | -------------------------------------------------------------------------------- /kubernetes/applications/security-policies.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: security-policies 6 | namespace: argocd 7 | spec: 8 | destination: 9 | server: https://kubernetes.default.svc 10 | project: default 11 | sources: 12 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 13 | targetRevision: main 14 | path: kubernetes/security/policies/vap 15 | syncPolicy: 16 | automated: 17 | prune: true 18 | selfHeal: true 19 | syncOptions: 20 | - ServerSideApply=true 21 | -------------------------------------------------------------------------------- /kubernetes/projects/steel-ambiguity/app-of-apps.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: steel-ambiguity 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: steel-ambiguity 9 | server: https://kubernetes.default.svc 10 | project: steel-ambiguity 11 | sources: 12 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-education.git 13 | targetRevision: main 14 | path: steel-ambiguity/applications 15 | directory: {} # We don't want to dive into the disabled directory, so recurse will not be set. 16 | -------------------------------------------------------------------------------- /kubernetes/projects/storm-paragraph/app-of-apps.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: storm-paragraph 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: storm-paragraph 9 | server: https://kubernetes.default.svc 10 | project: storm-paragraph 11 | sources: 12 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-education.git 13 | targetRevision: main 14 | path: storm-paragraph/applications 15 | directory: {} # We don't want to dive into the disabled directory, so recurse will not be set. 16 | -------------------------------------------------------------------------------- /kubernetes/applications/gateway-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: gateway-api 6 | namespace: argocd 7 | spec: 8 | destination: 9 | namespace: kube-system 10 | server: https://kubernetes.default.svc 11 | project: default 12 | sources: 13 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 14 | targetRevision: main 15 | path: kubernetes/core/gateway-api 16 | syncPolicy: 17 | automated: 18 | prune: true 19 | selfHeal: true 20 | syncOptions: 21 | - ServerSideApply=true 22 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/external-dns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | annotations: 5 | external-dns.alpha.kubernetes.io/hostname: argocd.cloud.danmanners.com 6 | external-dns.alpha.kubernetes.io/alias: "true" 7 | external-dns.alpha.kubernetes.io/ingress-hostname-source: annotation-only 8 | external-dns.alpha.kubernetes.io/target: unifi-home.homelab.danmanners.com 9 | external-dns.alpha.kubernetes.io/ttl: "300" 10 | name: argocd-extname 11 | namespace: argocd 12 | spec: 13 | externalName: unifi-home.homelab.danmanners.com 14 | sessionAffinity: None 15 | type: ExternalName 16 | -------------------------------------------------------------------------------- /kubernetes/core/openbao/readme.md: -------------------------------------------------------------------------------- 1 | # OpenBao 2 | 3 | Fork of Open Source Hashicorp Vault 4 | 5 | ## Template 6 | 7 | ```bash 8 | helm template openbao openbao/openbao \ 9 | --namespace openbao \ 10 | --create-namespace \ 11 | --version 0.12.0 \ 12 | --values kubernetes/core/openbao/values.yaml 13 | ``` 14 | 15 | ## Install 16 | 17 | ```bash 18 | helm repo add openbao https://openbao.github.io/openbao-helm 19 | helm repo update 20 | 21 | helm upgrade --install openbao openbao/openbao \ 22 | --namespace openbao \ 23 | --create-namespace \ 24 | --version 0.12.0 \ 25 | --values kubernetes/core/openbao/values.yaml 26 | ``` 27 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/cilium/bgp/CiliumBGPAdvertisement.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://kubernetes-schemas.ok8.sh/cilium.io/ciliumbgpadvertisement_v2alpha1.json 3 | apiVersion: "cilium.io/v2alpha1" 4 | kind: CiliumBGPAdvertisement 5 | metadata: 6 | name: cilium-bgp-advertisement 7 | labels: 8 | advertise: bgp 9 | spec: 10 | advertisements: 11 | # - advertisementType: "PodCIDR" 12 | - advertisementType: "Service" 13 | service: 14 | addresses: 15 | - LoadBalancerIP 16 | selector: 17 | matchExpressions: 18 | - { key: somekey, operator: NotIn, values: [ "never-used-value" ] } 19 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/cilium/bgp/CiliumBGPClusterConfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://kubernetes-schemas.ok8.sh/cilium.io/ciliumbgpclusterconfig_v2alpha1.json 3 | apiVersion: "cilium.io/v2alpha1" 4 | kind: CiliumBGPClusterConfig 5 | metadata: 6 | name: cilium-bgp-cluster-config 7 | spec: 8 | nodeSelector: 9 | matchLabels: 10 | kubernetes.io/os: linux 11 | bgpInstances: 12 | - name: "instance-64514" 13 | localASN: 64514 14 | peers: 15 | - name: "peer-64513-ipv4" 16 | peerASN: 64513 17 | peerAddress: "172.21.0.1" 18 | peerConfigRef: 19 | name: "cilium-bgp-peer-config-ipv4" 20 | -------------------------------------------------------------------------------- /kubernetes/applications/cnpg.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: cnpg 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 0.24.0 9 | spec: 10 | destination: 11 | namespace: database 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://cloudnative-pg.github.io/charts 16 | chart: cloudnative-pg 17 | targetRevision: *chartVersion 18 | syncPolicy: 19 | automated: 20 | prune: true 21 | selfHeal: true 22 | syncOptions: 23 | - ServerSideApply=true 24 | - CreateNamespace=true 25 | -------------------------------------------------------------------------------- /kubernetes/applications/education.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: education-projects 6 | namespace: argocd 7 | spec: 8 | destination: 9 | server: https://kubernetes.default.svc 10 | project: default 11 | sources: 12 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 13 | targetRevision: main 14 | path: kubernetes/projects 15 | kustomize: 16 | commonLabels: 17 | educational: "true" 18 | syncPolicy: 19 | automated: 20 | prune: true 21 | selfHeal: true 22 | syncOptions: 23 | - ServerSideApply=true 24 | -------------------------------------------------------------------------------- /kubernetes/applications/reflector.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: reflector 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 9.1.7 9 | spec: 10 | destination: 11 | namespace: kube-system 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://emberstack.github.io/helm-charts 16 | name: &name reflector 17 | chart: *name 18 | targetRevision: *chartVersion 19 | syncPolicy: 20 | automated: 21 | prune: true 22 | selfHeal: true 23 | syncOptions: 24 | - ServerSideApply=true 25 | -------------------------------------------------------------------------------- /kubernetes/core/openbao/cert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: openbao-tls-cert 5 | namespace: openbao 6 | annotations: 7 | cert-manager.io/issuer-kind: ClusterIssuer 8 | cert-manager.io/issuer-name: letsencrypt-dns01 9 | spec: 10 | secretName: openbao-tls-cert 11 | duration: 1128h # 47 days 12 | renewBefore: 168h # 7 days 13 | commonName: openbao.capi-core.homelab.danmanners.com 14 | dnsNames: 15 | - openbao.capi-core.homelab.danmanners.com 16 | issuerRef: 17 | name: letsencrypt-dns01 18 | kind: ClusterIssuer 19 | group: cert-manager.io 20 | usages: 21 | - server auth 22 | - client auth 23 | -------------------------------------------------------------------------------- /kubernetes/core/database/database.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.cnpg.io/v1 2 | kind: Cluster 3 | metadata: 4 | name: db 5 | namespace: database 6 | spec: 7 | instances: 3 8 | imageName: ghcr.io/cloudnative-pg/postgresql:17.5-bookworm 9 | primaryUpdateStrategy: unsupervised 10 | storage: 11 | size: 40Gi 12 | storageClass: ceph-block-retain 13 | superuserSecret: 14 | name: database-superuser 15 | enableSuperuserAccess: true 16 | postgresql: 17 | parameters: 18 | max_connections: "600" 19 | shared_buffers: 512MB 20 | resources: 21 | requests: 22 | memory: "2Gi" 23 | cpu: "200m" 24 | limits: 25 | memory: "4Gi" 26 | cpu: "2" 27 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/readme.md: -------------------------------------------------------------------------------- 1 | # ArgoCD 2 | 3 | ```bash 4 | # Install Base Resources; some resources may fail, we can loop through it twice to ensure all resources are applied 5 | for i in 1 2; do kubectl apply -k kubernetes/core/argocd --server-side; done 6 | 7 | # Template 8 | helm template argocd oci://ghcr.io/argoproj/argo-helm/argo-cd \ 9 | --namespace argocd \ 10 | --create-namespace \ 11 | --version 8.5.8 \ 12 | --skip-crds \ 13 | --values kubernetes/core/argocd/values.yaml 14 | 15 | # Deploy 16 | helm upgrade --install argocd oci://ghcr.io/argoproj/argo-helm/argo-cd \ 17 | --namespace argocd \ 18 | --version 8.5.8 \ 19 | --skip-crds \ 20 | --values kubernetes/core/argocd/values.yaml 21 | ``` 22 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/deletionProtection/restrict-namespace-delete.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://json.schemastore.org/yamllint.json 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: ValidatingAdmissionPolicy 5 | metadata: 6 | name: restrict-namespace-delete 7 | spec: 8 | failurePolicy: Fail 9 | matchConstraints: 10 | resourceRules: 11 | - apiGroups: [""] 12 | apiVersions: ["v1"] 13 | operations: ["DELETE"] 14 | resources: ["namespaces"] 15 | validations: 16 | - message: "Namespace deletion is restricted." 17 | reason: "Forbidden" 18 | expression: |- 19 | request.operation != "DELETE" ? true : false 20 | -------------------------------------------------------------------------------- /kubernetes/applications/istio-ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: istio-ingress 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 1.26.0 9 | spec: 10 | destination: 11 | namespace: istio-system 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://istio-release.storage.googleapis.com/charts 16 | name: &gw gateway 17 | chart: *gw 18 | targetRevision: *chartVersion 19 | syncPolicy: 20 | automated: 21 | prune: true 22 | selfHeal: true 23 | syncOptions: 24 | - ServerSideApply=true 25 | - CreateNamespace=true 26 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/tests/job-vap-test.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: escalator 6 | namespace: testing 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: ubuntu-privileged 12 | image: docker.io/library/ubuntu:22.04 13 | stdin: true 14 | tty: true 15 | command: [ "/bin/bash" ] 16 | args: [ "-c", "echo 'Hello, World, I ran successfully!'" ] 17 | volumeMounts: 18 | - name: host-root 19 | mountPath: /host-root 20 | volumes: 21 | - name: host-root 22 | hostPath: 23 | path: / 24 | type: Directory 25 | restartPolicy: Never 26 | -------------------------------------------------------------------------------- /kubernetes/core/harbor/certs/harbor-token-ca.yaml: -------------------------------------------------------------------------------- 1 | # https://cert-manager.io/docs/configuration/selfsigned/#bootstrapping-ca-issuers 2 | apiVersion: cert-manager.io/v1 3 | kind: Certificate 4 | metadata: 5 | name: harbor-token-ca 6 | spec: 7 | isCA: true 8 | commonName: harbor-token-ca 9 | secretName: harbor-token-ca-secret 10 | privateKey: 11 | algorithm: RSA 12 | size: 2048 13 | usages: 14 | - digital signature 15 | - key encipherment 16 | - server auth 17 | - client auth 18 | issuerRef: 19 | name: selfsigned-issuer 20 | kind: ClusterIssuer 21 | group: cert-manager.io 22 | --- 23 | apiVersion: cert-manager.io/v1 24 | kind: Issuer 25 | metadata: 26 | name: harbor-token-ca-issuer 27 | spec: 28 | ca: 29 | secretName: harbor-token-ca-secret 30 | -------------------------------------------------------------------------------- /kubernetes/core/harbor/certs/harbor-internal-ca.yaml: -------------------------------------------------------------------------------- 1 | # https://cert-manager.io/docs/configuration/selfsigned/#bootstrapping-ca-issuers 2 | apiVersion: cert-manager.io/v1 3 | kind: Certificate 4 | metadata: 5 | name: harbor-internal-ca 6 | spec: 7 | isCA: true 8 | commonName: harbor-internal-ca 9 | secretName: harbor-internal-ca-secret 10 | privateKey: 11 | algorithm: RSA 12 | size: 2048 13 | usages: 14 | - digital signature 15 | - key encipherment 16 | - server auth 17 | - client auth 18 | issuerRef: 19 | name: selfsigned-issuer 20 | kind: ClusterIssuer 21 | group: cert-manager.io 22 | --- 23 | apiVersion: cert-manager.io/v1 24 | kind: Issuer 25 | metadata: 26 | name: harbor-internal-ca-issuer 27 | spec: 28 | ca: 29 | secretName: harbor-internal-ca-secret 30 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph-external/cephfs-retain-sc.yaml: -------------------------------------------------------------------------------- 1 | allowVolumeExpansion: true 2 | apiVersion: storage.k8s.io/v1 3 | kind: StorageClass 4 | metadata: 5 | name: cephfs-retain 6 | parameters: 7 | clusterID: rook-ceph 8 | csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner 9 | csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph 10 | csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node 11 | csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph 12 | csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner 13 | csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph 14 | fsName: cephfs 15 | pool: cephfs_data 16 | provisioner: rook-ceph.cephfs.csi.ceph.com 17 | reclaimPolicy: Retain 18 | volumeBindingMode: Immediate 19 | -------------------------------------------------------------------------------- /kubernetes/applications/iperf3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: iperf3 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: default 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://bjw-s-labs.github.io/helm-charts 19 | chart: app-template 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/services/iperf3/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph-external/cluster.values.yaml: -------------------------------------------------------------------------------- 1 | # All values below are taken from the CephCluster CRD 2 | # -- Cluster configuration. 3 | # @default -- See [below](#ceph-cluster-spec) 4 | cephClusterSpec: 5 | external: 6 | enable: true 7 | crashCollector: 8 | disable: true 9 | healthCheck: 10 | daemonHealth: 11 | mon: 12 | disabled: false 13 | interval: 45s 14 | # -- A list of CephBlockPool configurations to deploy 15 | # @default -- See [below](#ceph-block-pools) 16 | cephBlockPools: {} 17 | 18 | # -- A list of CephFileSystem configurations to deploy 19 | # @default -- See [below](#ceph-file-systems) 20 | cephFileSystems: {} 21 | 22 | # -- A list of CephObjectStore configurations to deploy 23 | # @default -- See [below](#ceph-object-stores) 24 | cephObjectStores: {} 25 | -------------------------------------------------------------------------------- /kubernetes/services/jupyter/ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: gateway.networking.k8s.io/v1 3 | kind: HTTPRoute 4 | metadata: 5 | name: jupyter 6 | namespace: aiml 7 | annotations: 8 | external-dns.alpha.kubernetes.io/hostname: jupyter.capi-core.homelab.danmanners.com 9 | spec: 10 | hostnames: 11 | - jupyter.capi-core.homelab.danmanners.com 12 | parentRefs: 13 | - kind: Gateway 14 | group: gateway.networking.k8s.io 15 | name: gwapi 16 | namespace: default 17 | sectionName: https 18 | rules: 19 | - backendRefs: 20 | - group: "" 21 | kind: Service 22 | name: proxy-public 23 | port: 80 24 | weight: 1 25 | matches: 26 | - path: 27 | type: PathPrefix 28 | value: / 29 | timeouts: 30 | backendRequest: 0s 31 | request: 0s 32 | -------------------------------------------------------------------------------- /kubernetes/services/jupyter/values.yaml: -------------------------------------------------------------------------------- 1 | # fullnameOverride and nameOverride distinguishes blank strings, null values, 2 | # and non-blank strings. For more details, see the configuration reference. 3 | fullnameOverride: "" 4 | nameOverride: 5 | 6 | hub: 7 | db: 8 | type: sqlite-pvc 9 | pvc: 10 | accessModes: 11 | - ReadWriteOnce 12 | storage: 10Gi 13 | storageClassName: ceph-block-retain 14 | 15 | proxy: 16 | service: 17 | type: ClusterIP 18 | networkPolicy: 19 | ingress: 20 | - from: 21 | - podSelector: 22 | matchLabels: 23 | app.kubernetes.io/component: open-webui-ollama 24 | app.kubernetes.io/instance: ollama 25 | 26 | singleuser: 27 | storage: 28 | type: dynamic 29 | dynamic: 30 | storageClass: ceph-rbd 31 | pvcNameTemplate: "temp-pvc" 32 | -------------------------------------------------------------------------------- /kubernetes/applications/n8n.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: n8n 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: aiml 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://bjw-s-labs.github.io/helm-charts 19 | chart: app-template 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/services/n8n/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /kubernetes/projects/danger-million/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | projectName: "danger-million" 3 | projectNamespaceLabels: 4 | security: "restricted" 5 | educational: "true" 6 | 7 | oidc: 8 | enabled: true 9 | groupPrefix: "oidc:/" 10 | 11 | argo: 12 | appOfAppsNamespace: "argocd" 13 | targetRepoURL: "https://github.com/GoodMannersHosting/home-enterprise-education.git" 14 | targetRevision: "main" 15 | pathOverride: wander-winter/applications 16 | 17 | quotas: 18 | compute: 19 | cpu: "4000m" # Can pass an integer or m (milli) suffix for CPU; must end in '00m' if using millicores. 20 | memory: "8Gi" 21 | ephemeralStorage: "20Gi" 22 | storage: 23 | maxPvc: "10" # Number of Persistent Volume Claims 24 | requests: 25 | min: "1Gi" 26 | max: "4Gi" 27 | gpu: 28 | enabled: true 29 | count: "0" # Number of GPUs 30 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph-external/ceph-rbd-retain-sc.yaml: -------------------------------------------------------------------------------- 1 | allowVolumeExpansion: true 2 | apiVersion: storage.k8s.io/v1 3 | kind: StorageClass 4 | metadata: 5 | name: ceph-block-retain 6 | parameters: 7 | clusterID: rook-ceph 8 | csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner 9 | csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph 10 | csi.storage.k8s.io/fstype: ext4 11 | csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node 12 | csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph 13 | csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner 14 | csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph 15 | imageFeatures: layering 16 | imageFormat: "2" 17 | pool: nvme 18 | provisioner: rook-ceph.rbd.csi.ceph.com 19 | reclaimPolicy: Retain 20 | volumeBindingMode: Immediate 21 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/hostmount/deny-root-hostmount-pods.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://json.schemastore.org/yamllint.json 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: ValidatingAdmissionPolicy 5 | metadata: 6 | name: deny-root-hostmount-pods 7 | spec: 8 | failurePolicy: Fail 9 | matchConstraints: 10 | resourceRules: 11 | # Pod resources 12 | - apiGroups: [ "" ] 13 | apiVersions: [ "v1" ] 14 | operations: [ "CREATE", "UPDATE" ] 15 | resources: [ "pods" ] 16 | validations: 17 | - message: "Pods cannot mount the root of the host filesystem." 18 | reason: "Forbidden" 19 | expression: |- 20 | object.kind == 'Pod' ? ( 21 | !has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath) ? true : volume.hostPath.path != "/") 22 | ) : true 23 | -------------------------------------------------------------------------------- /kubernetes/applications/comfyui.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: comfyui 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: aiml 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://bjw-s-labs.github.io/helm-charts 19 | chart: app-template 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/services/comfyui/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /kubernetes/applications/coredns.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: coredns 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 1.43.0 9 | spec: 10 | destination: 11 | namespace: kube-system 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://coredns.github.io/helm 19 | chart: coredns 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/core/kube-system/coredns/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /kubernetes/applications/docling.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: docling 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: aiml 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://bjw-s-labs.github.io/helm-charts 19 | chart: app-template 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/services/docling/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /kubernetes/applications/k8s-mcp.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: k8s-mcp 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: aiml 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://bjw-s-labs.github.io/helm-charts 19 | chart: app-template 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/services/k8s-mcp/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /kubernetes/applications/disabled/tabbyml.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: tabbyml 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: aiml 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://bjw-s-labs.github.io/helm-charts 19 | chart: app-template 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/services/tabbyml/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /.github/workflows/opencode.yml: -------------------------------------------------------------------------------- 1 | name: opencode 2 | 3 | on: 4 | issue_comment: 5 | types: [created] 6 | 7 | jobs: 8 | opencode: 9 | runs-on: ubuntu-latest 10 | 11 | if: | 12 | contains(github.event.comment.body, ' /oc') || 13 | startsWith(github.event.comment.body, '/oc') || 14 | contains(github.event.comment.body, ' /opencode') || 15 | startsWith(github.event.comment.body, '/opencode') 16 | 17 | permissions: 18 | id-token: write 19 | contents: read 20 | pull-requests: read 21 | issues: read 22 | 23 | steps: 24 | - name: Checkout repository 25 | uses: actions/checkout@v5 26 | 27 | - name: Run opencode 28 | uses: sst/opencode/github@latest 29 | env: 30 | OLLAMA_API_KEY: ${{ secrets.OLLAMA_API_KEY }} 31 | with: 32 | model: "danollama/qwen3-coder:30b" -------------------------------------------------------------------------------- /kubernetes/core/gateway-api/cert-wildcard.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: wildcard 5 | namespace: default 6 | annotations: 7 | cert-manager.io/issuer-kind: ClusterIssuer 8 | cert-manager.io/issuer-name: letsencrypt-dns01 9 | spec: 10 | secretName: wildcard 11 | duration: 1128h # 47 days 12 | renewBefore: 168h # 7 days 13 | commonName: "*.cloud.danmanners.com" 14 | dnsNames: 15 | # - "*.capi-core.homelab.danmanners.com" 16 | - "*.cloud.danmanners.com" 17 | issuerRef: 18 | name: letsencrypt-dns01 19 | kind: ClusterIssuer 20 | group: cert-manager.io 21 | usages: 22 | - server auth 23 | - client auth 24 | secretTemplate: 25 | annotations: 26 | reflector.v1.k8s.emberstack.com/reflection-allowed: "true" 27 | reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true" 28 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/hostmount/deny-root-hostmount-jobs.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://json.schemastore.org/yamllint.json 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: ValidatingAdmissionPolicy 5 | metadata: 6 | name: deny-root-hostmount-jobs 7 | spec: 8 | failurePolicy: Fail 9 | matchConstraints: 10 | resourceRules: 11 | # Job resources 12 | - apiGroups: [ "batch" ] 13 | apiVersions: [ "v1" ] 14 | operations: [ "CREATE", "UPDATE" ] 15 | resources: [ "jobs" ] 16 | validations: 17 | - message: "Batch jobs cannot mount the root of the host filesystem." 18 | reason: "Forbidden" 19 | expression: |- 20 | object.kind == 'Job' ? ( 21 | !has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath) ? true : volume.hostPath.path != "/") 22 | ) : true 23 | -------------------------------------------------------------------------------- /kubernetes/applications/external-dns.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: external-dns 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 1.18.0 9 | spec: 10 | destination: 11 | namespace: kube-system 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://kubernetes-sigs.github.io/external-dns/ 19 | chart: external-dns 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/core/kube-system/external-dns/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /kubernetes/applications/metrics-server.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: metrics-server 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 3.12.2 9 | spec: 10 | destination: 11 | namespace: kube-system 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://kubernetes-sigs.github.io/metrics-server 19 | chart: metrics-server 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/core/kube-system/metrics-server/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | -------------------------------------------------------------------------------- /keys/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICVjCCAdygAwIBAgIUC+Me0ARMXcZVUNJniarXlqBXi8QwCgYIKoZIzj0EAwIw 3 | XTEhMB8GA1UEAwwYQ0EgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRswGQYDVQQLDBJJ 4 | QU0gUm9sZXMgQW55d2hlcmUxGzAZBgNVBAoMEkdvb2RNYW5uZXJzSG9zdGluZzAe 5 | Fw0yNTA2MjYwMzQ4NTVaFw0zNTA2MjQwMzQ4NTVaMF0xITAfBgNVBAMMGENBIENl 6 | cnRpZmljYXRlIEF1dGhvcml0eTEbMBkGA1UECwwSSUFNIFJvbGVzIEFueXdoZXJl 7 | MRswGQYDVQQKDBJHb29kTWFubmVyc0hvc3RpbmcwdjAQBgcqhkjOPQIBBgUrgQQA 8 | IgNiAAQSVvK+/jmKBLEjl1PfgAMldAMhTaq4mJ8cLRSMcowDREf72A/V/ppiu/3K 9 | mSioWUkKoWop+pIQH1r12sVVFY3sQ5pXyOWnongS2UvH09MhiXaI65uZMb4wc7On 10 | P7DS0POjXTBbMAsGA1UdDwQEAwIBhjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBQO 11 | xhr3tvktJxg40amP8t2/8HAM0jAfBgNVHSMEGDAWgBQOxhr3tvktJxg40amP8t2/ 12 | 8HAM0jAKBggqhkjOPQQDAgNoADBlAjAs3YbPJQ8Vqcevd3Y0YE3pmOirOXW5jUSR 13 | hQz5LSiHDCmqMjUhAMNq1UMeOi/eeisCMQD4s4xt3BypetYj+UxxrPKHKe1XHEjM 14 | 4bZE6D17k3ZpRr+ukMtS3Hx4xnOX2g5eygk= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /kubernetes/applications/sealed-secrets.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: sealed-secrets 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 2.17.2 9 | spec: 10 | destination: 11 | namespace: sealed-secrets 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://bitnami-labs.github.io/sealed-secrets 19 | chart: sealed-secrets 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/core/sealed-secrets/values.yaml 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true 28 | syncOptions: 29 | - ServerSideApply=true 30 | - CreateNamespace=true 31 | -------------------------------------------------------------------------------- /kubernetes/applications/harbor.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: harbor 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 1.17.1 9 | spec: 10 | destination: 11 | namespace: harbor 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &repo https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/core/harbor 18 | - repoURL: *repo 19 | targetRevision: main 20 | ref: values 21 | - repoURL: https://helm.goharbor.io 22 | chart: harbor 23 | targetRevision: *chartVersion 24 | helm: 25 | valueFiles: 26 | - $values/kubernetes/core/harbor/values.yaml 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | -------------------------------------------------------------------------------- /kubernetes/applications/monitoring.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: monitoring 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 77.11.0 9 | spec: 10 | destination: 11 | namespace: monitoring 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - name: controller 19 | repoURL: ghcr.io/prometheus-community/charts 20 | chart: kube-prometheus-stack 21 | targetRevision: *chartVersion 22 | helm: 23 | valueFiles: 24 | - $values/kubernetes/core/monitoring/values.yaml 25 | syncPolicy: 26 | automated: 27 | prune: true 28 | selfHeal: true 29 | syncOptions: 30 | - ServerSideApply=true 31 | - CreateNamespace=true 32 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/hostmount/deny-root-hostmount-cronjobs.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://json.schemastore.org/yamllint.json 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: ValidatingAdmissionPolicy 5 | metadata: 6 | name: deny-root-hostmount-cronjobs 7 | spec: 8 | failurePolicy: Fail 9 | matchConstraints: 10 | resourceRules: 11 | # Cronjob resources 12 | - apiGroups: [ "batch" ] 13 | apiVersions: [ "v1" ] 14 | operations: [ "CREATE", "UPDATE" ] 15 | resources: [ "cronjobs" ] 16 | validations: 17 | - message: "Batch jobs cannot mount the root of the host filesystem." 18 | reason: "Forbidden" 19 | expression: |- 20 | object.kind == 'CronJob' ? ( 21 | !has(object.spec.jobTemplate.spec.template.spec.volumes) || object.spec.jobTemplate.spec.template.spec.volumes.all(volume, !has(volume.hostPath) ? true : volume.hostPath.path != "/") 22 | ) : true 23 | -------------------------------------------------------------------------------- /kubernetes/applications/cilium.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: cilium 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 1.17.5 9 | spec: 10 | destination: 11 | namespace: kube-system 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &url https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/core/kube-system/cilium/bgp 18 | - repoURL: *url 19 | targetRevision: main 20 | ref: values 21 | - repoURL: https://helm.cilium.io/ 22 | chart: cilium 23 | targetRevision: *chartVersion 24 | helm: 25 | valueFiles: 26 | - $values/kubernetes/core/kube-system/cilium/values.yaml 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | -------------------------------------------------------------------------------- /kubernetes/applications/keycloak.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: keycloak 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: keycloak 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &repo https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/core/keycloak 18 | - repoURL: *repo 19 | targetRevision: main 20 | ref: values 21 | - repoURL: https://bjw-s-labs.github.io/helm-charts 22 | chart: app-template 23 | targetRevision: *chartVersion 24 | helm: 25 | valueFiles: 26 | - $values/kubernetes/core/keycloak/values.yaml 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | -------------------------------------------------------------------------------- /kubernetes/applications/powerdns.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: powerdns 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: powerdns 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &repo https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/core/powerdns 18 | - repoURL: *repo 19 | targetRevision: main 20 | ref: values 21 | - repoURL: https://bjw-s-labs.github.io/helm-charts 22 | chart: app-template 23 | targetRevision: *chartVersion 24 | helm: 25 | valueFiles: 26 | - $values/kubernetes/core/powerdns/values.yaml 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | -------------------------------------------------------------------------------- /kubernetes/core/gatus/resources/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | connectivity: 3 | checker: 4 | target: 1.1.1.1:53 5 | interval: 30s 6 | 7 | metrics: true 8 | 9 | ui: 10 | title: Status | Gatus 11 | header: Status 12 | logo: https://avatars.githubusercontent.com/u/17593824 13 | link: https://github.com/danmanners 14 | buttons: 15 | - name: GitHub Profile 16 | link: https://github.com/danmanners 17 | - name: Homelab Repository 18 | link: https://github.com/GoodMannersHosting/home-enterprise-labops 19 | 20 | storage: 21 | type: sqlite 22 | path: /database/gatus.db 23 | maximum-number-of-results: 200 24 | 25 | web: 26 | port: 80 27 | 28 | endpoints: 29 | - name: Homelab Unifi 30 | url: "1.1.1.1" # Address of the DNS server to use 31 | interval: 5m 32 | dns: 33 | query-name: "unifi-home.homelab.danmanners.com" 34 | query-type: "A" 35 | conditions: 36 | - "[BODY] == pat(*.*.*.*)" 37 | - "[DNS_RCODE] == NOERROR" 38 | -------------------------------------------------------------------------------- /kubernetes/applications/disabled/palworld.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: palworld 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: palworld 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &repo https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/services/palworld 18 | - repoURL: *repo 19 | targetRevision: main 20 | ref: values 21 | - repoURL: https://bjw-s-labs.github.io/helm-charts 22 | chart: app-template 23 | targetRevision: *chartVersion 24 | helm: 25 | valueFiles: 26 | - $values/kubernetes/services/palworld/values.yaml 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | -------------------------------------------------------------------------------- /kubernetes/applications/gatus.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: gatus 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.1.2 9 | spec: 10 | destination: 11 | namespace: gatus 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &repo https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/core/gatus 18 | - repoURL: *repo 19 | targetRevision: main 20 | ref: values 21 | - repoURL: https://bjw-s-labs.github.io/helm-charts 22 | chart: app-template 23 | targetRevision: *chartVersion 24 | helm: 25 | valueFiles: 26 | - $values/kubernetes/core/gatus/values.yaml 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | - CreateNamespace=true 34 | -------------------------------------------------------------------------------- /kubernetes/applications/forgejo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: forgejo 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 4.4.0 9 | spec: 10 | destination: 11 | namespace: forgejo 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &repo https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/core/forgejo 18 | - repoURL: *repo 19 | targetRevision: main 20 | ref: values 21 | - repoURL: https://bjw-s-labs.github.io/helm-charts 22 | chart: app-template 23 | targetRevision: *chartVersion 24 | helm: 25 | valueFiles: 26 | - $values/kubernetes/core/forgejo/values.yaml 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | - CreateNamespace=true 34 | -------------------------------------------------------------------------------- /.github/renovate.json5: -------------------------------------------------------------------------------- 1 | { 2 | $schema: "https://docs.renovatebot.com/renovate-schema.json", 3 | extends: ["config:base"], 4 | dependencyDashboard: true, 5 | argocd: { 6 | enabled: true, 7 | fileMatch: ["(?:^|/)kubernetes/applications/([^/\r\n]+)"], 8 | }, 9 | packageRules: [ 10 | { 11 | matchPackageNames: ["kustomize"], 12 | enabled: false, 13 | }, 14 | ], 15 | regexManagers: [ 16 | { 17 | fileMatch: ["kustomization.ya??ml$"], 18 | matchStrings: [ 19 | "datasource=(?\\S+) depName=(?\\S+)\n*[^/]+://[^/]+/[^/]+/[^/]+/(?[^/]+)/", 20 | ], 21 | datasourceTemplate: "github-releases", 22 | }, 23 | { 24 | customType: "regex", 25 | datasourceTemplate: "docker", 26 | managerFilePatterns: ["/(^|/)Chart\\.yaml$/"], 27 | matchStrings: [ 28 | '#\\s?renovate: image=(?.*?)\\s?appVersion:\\s?\\"?(?[\\w+\\.\\-]*)"', 29 | ], 30 | }, 31 | ], 32 | } 33 | -------------------------------------------------------------------------------- /kubernetes/applications/ollama.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: ollama 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 8.9.0 9 | spec: 10 | destination: 11 | namespace: aiml 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | ref: values 18 | - repoURL: https://helm.openwebui.com/ 19 | chart: open-webui 20 | targetRevision: *chartVersion 21 | helm: 22 | valueFiles: 23 | - $values/kubernetes/services/open-webui/values.yaml 24 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 25 | targetRevision: main 26 | path: kubernetes/services/open-webui 27 | syncPolicy: 28 | automated: 29 | prune: true 30 | selfHeal: true 31 | syncOptions: 32 | - ServerSideApply=true 33 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph/operator.values.yaml: -------------------------------------------------------------------------------- 1 | operatorNamespace: rook-ceph 2 | clusterName: helo 3 | toolbox: 4 | enabled: true 5 | containerSecurityContext: 6 | runAsNonRoot: true 7 | runAsUser: 2016 8 | runAsGroup: 2016 9 | capabilities: 10 | drop: [ "ALL" ] 11 | # -- Toolbox resources 12 | resources: 13 | limits: 14 | memory: "1Gi" 15 | requests: 16 | cpu: "100m" 17 | memory: "128Mi" 18 | 19 | csi: 20 | cephFSKernelMountOptions: ms_mode=prefer-crc 21 | enableCephfsDriver: false 22 | enableCephfsSnapshotter: false 23 | enableLiveness: true 24 | serviceMonitor: 25 | enabled: true 26 | 27 | enableDiscoveryDaemon: true 28 | 29 | image: 30 | repository: ghcr.io/rook/ceph 31 | 32 | monitoring: 33 | enabled: false 34 | 35 | ingress: 36 | dashboard: {} 37 | 38 | cephFileSystems: {} 39 | cephObjectStores: {} 40 | 41 | cephFileSystemVolumeSnapshotClass: 42 | enabled: false 43 | 44 | cephBlockPoolsVolumeSnapshotClass: 45 | enabled: false 46 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/tlsroute.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: gateway.networking.k8s.io/v1alpha2 3 | kind: TLSRoute 4 | metadata: 5 | name: argocd 6 | namespace: argocd 7 | annotations: 8 | external-dns.alpha.kubernetes.io/controller: "false" 9 | # external-dns.alpha.kubernetes.io/alias: "true" 10 | # external-dns.alpha.kubernetes.io/hostname: argocd.cloud.danmanners.com 11 | # external-dns.alpha.kubernetes.io/ingress-hostname-source: annotation-only 12 | # external-dns.alpha.kubernetes.io/target: unifi-home.homelab.danmanners.com 13 | # external-dns.alpha.kubernetes.io/ttl: "300" 14 | spec: 15 | hostnames: 16 | - argocd.cloud.danmanners.com 17 | parentRefs: 18 | - name: gwapi 19 | namespace: default 20 | kind: Gateway 21 | group: gateway.networking.k8s.io 22 | sectionName: argocd 23 | rules: 24 | - name: https 25 | backendRefs: 26 | - name: argocd-server 27 | kind: Service 28 | group: "" 29 | port: 443 30 | weight: 1 31 | -------------------------------------------------------------------------------- /unifi/bgp.conf: -------------------------------------------------------------------------------- 1 | router bgp 64513 2 | bgp router-id 172.21.0.1 3 | no bgp ebgp-requires-policy 4 | no bgp default ipv4-unicast 5 | no bgp network import-check 6 | 7 | neighbor k8s peer-group 8 | neighbor k8s remote-as 64514 9 | ! These are agressive timers, you might want to double those values 10 | neighbor k8s timers 5 15 11 | neighbor k8s timers connect 10 12 | neighbor k8s activate 13 | ! neighbor k8s soft-reconfiguration inbound 14 | 15 | neighbor 172.21.0.10 peer-group k8s 16 | neighbor 172.21.0.11 peer-group k8s 17 | neighbor 172.21.0.12 peer-group k8s 18 | neighbor 172.21.0.13 peer-group k8s 19 | neighbor 172.21.0.14 peer-group k8s 20 | neighbor 172.21.0.15 peer-group k8s 21 | neighbor 172.21.0.16 peer-group k8s 22 | neighbor 172.21.0.17 peer-group k8s 23 | neighbor 172.21.0.18 peer-group k8s 24 | neighbor 172.21.0.19 peer-group k8s 25 | neighbor 172.21.0.98 peer-group k8s 26 | 27 | address-family ipv4 unicast 28 | neighbor k8s next-hop-self 29 | neighbor k8s activate 30 | exit-address-family -------------------------------------------------------------------------------- /kubernetes/core/harbor/networking/httproute.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: gateway.networking.k8s.io/v1 3 | kind: HTTPRoute 4 | metadata: 5 | name: harbor 6 | annotations: 7 | external-dns.alpha.kubernetes.io/controller: "false" 8 | gatus.home-operations.com/enabled: "true" 9 | gatus.home-operations.com/endpoint: |- 10 | name: Harbor 11 | conditions: 12 | - "[STATUS] == 200" 13 | url: http://harbor.harbor.svc.cluster.local/ 14 | method: HEAD 15 | spec: 16 | hostnames: 17 | - harbor.cloud.danmanners.com 18 | parentRefs: 19 | - kind: Gateway 20 | group: gateway.networking.k8s.io 21 | name: gwapi 22 | namespace: default 23 | sectionName: https-cloud 24 | rules: 25 | - name: harbor 26 | backendRefs: 27 | - group: "" 28 | kind: Service 29 | name: harbor 30 | port: 80 31 | weight: 1 32 | matches: 33 | - path: 34 | type: PathPrefix 35 | value: / 36 | timeouts: 37 | backendRequest: 0s 38 | request: 0s 39 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph/ceph-retain-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: ceph-block-retain 5 | annotations: 6 | storageclass.kubernetes.io/is-default-class: "false" 7 | allowVolumeExpansion: true 8 | mountOptions: 9 | - discard 10 | parameters: 11 | clusterID: rook-ceph 12 | compression_algorithm: zstd 13 | compression_mode: aggressive 14 | csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner 15 | csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph 16 | csi.storage.k8s.io/fstype: ext4 17 | csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node 18 | csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph 19 | csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner 20 | csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph 21 | imageFeatures: layering,fast-diff,object-map,deep-flatten,exclusive-lock 22 | imageFormat: "2" 23 | pool: ceph-blockpool 24 | provisioner: rook-ceph.rbd.csi.ceph.com 25 | reclaimPolicy: Retain 26 | volumeBindingMode: Immediate 27 | -------------------------------------------------------------------------------- /scripts/sealed-secrets-generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if a number of days are specified. Otherwise, default to 400 days. 4 | DAYS=${1:-400} 5 | 6 | check_existing_files() { 7 | if [[ -f "keys/sealed-secret.crt" || -f "keys/sealed-secret.key" ]]; then 8 | echo "Error: keys/sealed-secret.crt or keys/sealed-secret.key already exist." 9 | echo "We don't want to overwrite existing keys. That is a bad idea." 10 | exit 1 11 | fi 12 | } 13 | 14 | # This script generates a self-signed certificate and private key for use with Sealed Secrets. 15 | # It checks if the keys already exist and if so, it exits with an error message. 16 | # Usage: ./scripts/sealed-secrets-generate.sh 17 | 18 | # Ensure the keys directory exists 19 | mkdir -p keys 20 | 21 | # Check if the keys already exist 22 | check_existing_files 23 | 24 | # Generate a self-signed certificate and private key 25 | openssl req -x509 -days ${DAYS} \ 26 | -nodes -newkey rsa:4096 \ 27 | -keyout keys/sealed-secret.key \ 28 | -out keys/sealed-secret.crt \ 29 | -subj "/CN=sealed-secret/O=sealed-secret" \ 30 | >/dev/null 2>&1 31 | -------------------------------------------------------------------------------- /kubernetes/applications/nvidia.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: nvdp 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 0.17.3 9 | spec: 10 | destination: 11 | namespace: nvidia-device-plugin 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: main 17 | path: kubernetes/core/runtimes 18 | directory: 19 | recurse: true 20 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 21 | targetRevision: main 22 | ref: values 23 | - repoURL: https://nvidia.github.io/k8s-device-plugin 24 | targetRevision: *chartVersion 25 | chart: nvidia-device-plugin 26 | helm: 27 | valueFiles: 28 | - $values/kubernetes/services/nvdp/values.yaml 29 | syncPolicy: 30 | automated: 31 | prune: true 32 | selfHeal: true 33 | syncOptions: 34 | - ServerSideApply=true 35 | - CreateNamespace=true 36 | -------------------------------------------------------------------------------- /kubernetes/projects/wander-winter/appproject.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: &ns wander-winter 5 | namespace: argocd 6 | spec: 7 | description: Educational environment for the Wander Winter Namespace 8 | roles: 9 | - name: admin 10 | description: "Admins can do anything for their project" 11 | groups: 12 | - *ns 13 | policies: 14 | - p, proj:wander-winter:admin, applications, *, *, allow 15 | clusterResourceBlacklist: 16 | - group: "*" 17 | kind: "*" 18 | clusterResourceWhitelist: 19 | - group: "" 20 | kind: "persistentvolumes" 21 | destinations: 22 | # Allow deployments to wander-winter namespace 23 | - namespace: *ns 24 | server: https://kubernetes.default.svc 25 | sourceNamespaces: 26 | - *ns 27 | namespaceResourceWhitelist: 28 | - group: "*" 29 | kind: "*" 30 | namespaceResourceBlacklist: 31 | - group: "" 32 | kind: "ResourceQuota" 33 | - group: "ceph.rook.io" 34 | kind: "*" 35 | - group: "argoproj.io" 36 | kind: "appprojects" 37 | sourceRepos: 38 | - "*" 39 | -------------------------------------------------------------------------------- /kubernetes/core/forgejo/secret.meilisearch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | name: forgejo-meilisearch-credentials 6 | namespace: forgejo 7 | spec: 8 | encryptedData: 9 | masterkey: AgAYzgQ3lneNemQJtEsC0CL21QW34A1yxqQWvDyVaZgXk+RPOzeEiH+hSRltACm+gp8JAAkV0QY8p3tSbNOGjevNBrqJ5sNRVDASz+WxjCG4Q4yAsDc6rrlqMvdp0hgz0SXdTzE462hYCy4cgVLsVDpRxtU2H8kQD9+3frzymmQoysD2OQFXtdTggp7eSYD3uIPFQbSTcnjplxANaplneREr1D9R4KaOlBmemjykys1KzMmygd0QEK9/S8JidjmSAx6TeN3RdV6kaOX7307rrMOacq+UpeC9TGCY0n/WIZV6X19+JHE6vreJPGlkZJdgSS4XFz4tmGoS+FVu79FIKloQUPqOacVehqGk8Z+cL/Q3wqOfF9Gztj4gxSXpgDYGm2/FKEVGi7YeEOEBPhW3C8dqTIF/eOfgSc9z1n9Ks381QRW9PARKF3gMg8SauplZ5fRslflGzBe2xaAd6+TBt/Yk17dc6ls6n/MJiHdZRXDYEKTuizQpj98wHaQ2C/yb6qZs2C/X3dEwvWXEC5NkqXslL4kN1pGfuQnD621DzAo9+zP/T1iluFSGsiJ2+GPCUIM3ERlnDyePADC80wPKdbFyY1QJ18qCryM6Tsf+QzdMWm5MxUQVLXc2TqbCDmHah1F8ZIjRbav3D8W31ANmPk5h+7FfqlRF3fSxl0ZgB+3MReglG65OMc3jePvodoF0Tl08ADJi9kPYz308IfyUep+VUbI54irXjTxnG3c+BjgnCnrb4FZ7WYg/OSobaGa6Caf6EAldQF5UVwgDbhT80OFZ 10 | template: 11 | metadata: 12 | name: forgejo-meilisearch-credentials 13 | namespace: forgejo 14 | type: Opaque 15 | -------------------------------------------------------------------------------- /kubernetes/projects/danger-million/appproject.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: &ns danger-million 5 | namespace: argocd 6 | spec: 7 | description: Educational environment for the Wander Winter Namespace 8 | roles: 9 | - name: admin 10 | description: "Admins can do anything for their project" 11 | groups: 12 | - *ns 13 | policies: 14 | - p, proj:danger-million:admin, applications, *, *, allow 15 | clusterResourceBlacklist: 16 | - group: "*" 17 | kind: "*" 18 | clusterResourceWhitelist: 19 | - group: "" 20 | kind: "persistentvolumes" 21 | destinations: 22 | # Allow deployments to danger-million namespace 23 | - namespace: *ns 24 | server: https://kubernetes.default.svc 25 | sourceNamespaces: 26 | - *ns 27 | namespaceResourceWhitelist: 28 | - group: "*" 29 | kind: "*" 30 | namespaceResourceBlacklist: 31 | - group: "" 32 | kind: "ResourceQuota" 33 | - group: "ceph.rook.io" 34 | kind: "*" 35 | - group: "argoproj.io" 36 | kind: "appprojects" 37 | sourceRepos: 38 | - "*" 39 | -------------------------------------------------------------------------------- /kubernetes/projects/steel-ambiguity/appproject.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: &ns steel-ambiguity 5 | namespace: argocd 6 | spec: 7 | description: Educational environment for the Steel Ambiguity Namespace 8 | roles: 9 | - name: admin 10 | description: "Admins can do anything for their project" 11 | groups: 12 | - *ns 13 | policies: 14 | - p, proj:steel-ambiguity:admin, applications, *, *, allow 15 | clusterResourceBlacklist: 16 | - group: "*" 17 | kind: "*" 18 | clusterResourceWhitelist: 19 | - group: "" 20 | kind: "persistentvolumes" 21 | destinations: 22 | # Allow deployments to steel-ambiguity namespace 23 | - namespace: *ns 24 | server: https://kubernetes.default.svc 25 | sourceNamespaces: 26 | - *ns 27 | namespaceResourceWhitelist: 28 | - group: "*" 29 | kind: "*" 30 | namespaceResourceBlacklist: 31 | - group: "" 32 | kind: "ResourceQuota" 33 | - group: "ceph.rook.io" 34 | kind: "*" 35 | - group: "argoproj.io" 36 | kind: "appprojects" 37 | sourceRepos: 38 | - "*" 39 | -------------------------------------------------------------------------------- /kubernetes/projects/storm-paragraph/appproject.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: &ns storm-paragraph 5 | namespace: argocd 6 | spec: 7 | description: Educational environment for the Storm Paragraph Namespace 8 | roles: 9 | - name: admin 10 | description: "Admins can do anything for their project" 11 | groups: 12 | - *ns 13 | policies: 14 | - p, proj:storm-paragraph:admin, applications, *, *, allow 15 | clusterResourceBlacklist: 16 | - group: "*" 17 | kind: "*" 18 | clusterResourceWhitelist: 19 | - group: "" 20 | kind: "persistentvolumes" 21 | destinations: 22 | # Allow deployments to storm-paragraph namespace 23 | - namespace: *ns 24 | server: https://kubernetes.default.svc 25 | sourceNamespaces: 26 | - *ns 27 | namespaceResourceWhitelist: 28 | - group: "*" 29 | kind: "*" 30 | namespaceResourceBlacklist: 31 | - group: "" 32 | kind: "ResourceQuota" 33 | - group: "ceph.rook.io" 34 | kind: "*" 35 | - group: "argoproj.io" 36 | kind: "appprojects" 37 | sourceRepos: 38 | - "*" 39 | -------------------------------------------------------------------------------- /kubernetes/services/open-webui/oidc-secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: open-webui-oidc-secret 7 | namespace: aiml 8 | spec: 9 | encryptedData: 10 | clientSecret: AgCKdNlDyfbOr/3n9hltfnvzfm3ABaSsmIiRqsPIgAPpClZZyyQqUxNbqbdXfprUHCaSp1ozvqPUNTaOB/9GS9PsF9X2i2SHj/802rp2xqz57mmIzZKie0kcAmy/pz4zLlKXY6tUlOIwKzZoZV3SvdP6yAJHAqDYy9SELH/06kq8hxCt6yJIof3uTVOvg6vn/pfl1MpGt21bnhgFPvaaoxzXQeehtFRngUq+b+hPevBy0o52ixepIO7eNXqXVBMyFqBUTmULmBqFQEmPEeyjZfiZPoOOKqbyDDttpjUHWYHwS46T8J6TbM7rOHFcPlUbYAZjpr/dD3ersruim7oZdxpKRyY4QYEtWDZk+8HcqjxZkdwkICgsrvXCAd+mfqIIMPk0AliFgCQyge6aJURHjZ9JlI7gyhKBmZLx63+rFXdAfjxL2LKX3jlV1DInHELDFcuX/VK+MwGgS3W2mtpYUvlg5s14eHq+FWn8ONN74amLQw4tLtMJWM3j+pJ+9xK+ASY8KJk4TUJS+/meZsmM1F+dZQ6qZadGmO7+U9XEksyb2ojkqHJmau9KnnkF1yyTVPEQkJOERwBiTTYyR3CoUFqNE/ScH84P1CaIHBJJMtxEecmzPRjXY9UfPKNNIyeFf9jw7JOyY0jAPQ3o/6E3KMKK+lk7mEcKQ0BojnwDgsLSRJAUot6+w8GdFX/H17WiELNQ7lzwrZmPVtZGnosE3vxyalt8VBkVA0Ifj+ct1aTr8A== 11 | template: 12 | metadata: 13 | creationTimestamp: null 14 | name: open-webui-oidc-secret 15 | namespace: aiml 16 | type: Opaque 17 | -------------------------------------------------------------------------------- /kubernetes/core/keycloak/keycloak-superuser-secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: keycloak-superuser-secret 7 | namespace: keycloak 8 | spec: 9 | encryptedData: 10 | password: AgALzqzimY58crbo7hq2+1Bg0km5YZBr5hISqYX3IYGIDPdbzmpDGdhrZ2T7gRANezEo55++EAMeNNrIa5Zg2umKkEaDmAGsBtNNClNDecxXZYTn7tT+CP6xpCdwJNPUSkXKiEsiHTUPyOpjpO6Kx2sP/PxWFrJLJhB50NJ0EnH8h1EIjRIFiciXp+t35v7tVYJa8E8RMKt80VGvbrrixMgL8CfTj8yPFJMh7V20l4FwhUudI0UDop/PHnboVD2jFl3DLBhr/SoFIVZ24OMd496mo79p5VSDPTdFo79trGow+5rnIfFsWQ4W5kEknu3RcUEp1jqrdjSrkhlNDVaEM1F/vYlkOFHJKaW0CCjhVx5M0ksm82ZnY2QEcMrF1TH5/c6gS4tLLhCZiHNlfINpQ00VTJuuQQpEzkbjdus873oq7xPVZkSOmEmThYQVBGW/rI6K1wqfg1kyAwqfPSCeRt2t21K38BeXCpetyEUhILIi1ABbowrqDM9snf46uwPLwexg7Ix47d5m04cO4j4O7ES6a/TW/XXAE4W9PhmLKdmbrER19RNMpLmRi0FWAdmJZrZxBATl73twvwgWeUnwHy6ossSYd2Ff+q/MAiNiThqcpwuzrez4Puznr/aGD4SWVs4j0TCwKkImQolbBR63y5JO+gNkWry7/Vz52NrcSQBtIIP3R0ZwFt1RuA5yW8klL1YeC1fHTWS9uVNwDdi/GZKwA01Ot+iH4LKSYOeuYG3qU+LdwA== 11 | template: 12 | metadata: 13 | creationTimestamp: null 14 | name: keycloak-superuser-secret 15 | namespace: keycloak 16 | type: Opaque 17 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/hostmount/deny-root-hostmount-apps.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://json.schemastore.org/yamllint.json 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: ValidatingAdmissionPolicy 5 | metadata: 6 | name: deny-root-hostmount-apps 7 | spec: 8 | failurePolicy: Fail 9 | matchConstraints: 10 | resourceRules: 11 | # Workload resources 12 | - &apps 13 | apiGroups: ["apps"] 14 | apiVersions: &v1 ["v1"] 15 | operations: &ops ["CREATE", "UPDATE"] 16 | resources: ["deployments"] 17 | - <<: *apps 18 | resources: ["replicasets"] 19 | - <<: *apps 20 | resources: ["statefulsets"] 21 | - <<: *apps 22 | resources: ["daemonsets"] 23 | validations: 24 | - message: "Workloads cannot mount the root of the host filesystem." 25 | reason: "Forbidden" 26 | expression: |- 27 | object.kind in [ 'Deployment', 'ReplicaSet', 'StatefulSet', 'DaemonSet' ] ? ( 28 | !has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath) ? true : volume.hostPath.path != "/") 29 | ) : true 30 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/deletionProtection/restrict-educational-delete.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://json.schemastore.org/yamllint.json 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: ValidatingAdmissionPolicy 5 | metadata: 6 | name: protect-quota-and-limit-resources 7 | spec: 8 | failurePolicy: Fail 9 | matchConstraints: 10 | resourceRules: 11 | - apiGroups: [""] 12 | apiVersions: ["v1"] 13 | operations: ["DELETE"] 14 | resources: ["resourcequotas", "limitranges"] 15 | validations: 16 | - message: "ResourceQuota and LimitRange resources cannot be deleted to maintain resource governance." 17 | reason: "Forbidden" 18 | expression: "false" 19 | --- 20 | # yaml-language-server: $schema=https://json.schemastore.org/yamllint.json 21 | apiVersion: admissionregistration.k8s.io/v1 22 | kind: ValidatingAdmissionPolicyBinding 23 | metadata: 24 | name: protect-quota-and-limit-resources-educational 25 | spec: 26 | policyName: protect-quota-and-limit-resources 27 | validationActions: 28 | - Deny 29 | matchResources: 30 | objectSelector: 31 | matchLabels: 32 | educational: "true" 33 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/oidc-secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: argocd-oidc-secret 7 | namespace: argocd 8 | spec: 9 | encryptedData: 10 | oidc.keycloak.clientSecret: AgATo5pAUK0puVql7Q5Zrwe/WSarcsnn+iqrHypGGZaMcE4GJX6+THXgYc31vHIHgPMPxjGGp5J1GAS6xvwG6CCSAS//mEHMqR7rpm15vr5V5Eu6TtL4HyxaOQWvnFph2dRG0gHPVYNcN402rSMBPZ1TJGB6H8H1TooDUS3EXBi60ClcG+sucdC8vafxcSyUu57rBOmmKES5OsWNctzVhbARH6mBYdwwWJPvdJu4rQGZS8XBy6I0hJOgIUMyANGcopEac/U2mA/PVlouOuQBeq4l22gk7RrwW7L1pspx3dbekvwIlg0P6JGh4IyRIlcUG0PIGoxlsVgwvtGqf/UQpBE6Q6Ag+zb5O9sMfVgJ5jYcsjs6vrW2xWq3RcQpEKCAQboXSqZqpCnncH2sWpHOZGxEWFalTfgfazDMLlosOgxU3fSZA7IlJYIB7FizmikyIr8CznQQLWv4E9szCL7cpxC386bHrAHhODpxrzPv1eNnI1vBUDiZ5Nm5Whf6Ia3gjIKbJ+rtHePPKuqdb6SfjNwO93/k3LYyyw5dseZR/6ll37QfoLYAnwjTNEAlwdnN+VmMGSw7RPa0WQ2u5fXl3OIpqW3ylVkga35BF8MxwNskqt7wFvaJhnfi+3WsHEVUFkekOm4EHi0c/F32d2FUaoXTmceNZZ9PjCVhNfEkJCL/CCyACkxW8zcEOZcazzld9G/RsKbtQ7gbrD3XlwhM+LIU3wqyVvimuZf7MUYxylxGlg== 11 | template: 12 | metadata: 13 | creationTimestamp: null 14 | labels: 15 | app.kubernetes.io/part-of: argocd 16 | name: argocd-oidc-secret 17 | namespace: argocd 18 | -------------------------------------------------------------------------------- /kubernetes/services/librechat/readme.md: -------------------------------------------------------------------------------- 1 | # Manualy Deployment of LibreChat on Kubernetes 2 | 3 | GitHub Repo: [danny-avila/LibreChat](https://github.com/danny-avila/LibreChat) 4 | 5 | > [!NOTE] 6 | > I decided not to go with this tool, as I personally found it less user friendly compared to Open WebUI. However, for those interested in deploying LibreChat on Kubernetes, the following instructions can be followed. 7 | 8 | ## Deployment 9 | 10 | ```bash 11 | # Deploy the configmap and secret 12 | kubectl apply -k kubernetes/services/librechat 13 | 14 | # Add Helm Repositories 15 | helm repo add otwld https://helm.otwld.com/ 16 | helm repo add bjw-s https://bjw-s-labs.github.io/helm-charts 17 | helm repo update 18 | 19 | # Deploy the two Helm charts 20 | ## Deploy the Ollama Embeddings Service 21 | helm template embeddings --namespace aiml \ 22 | otwld/ollama --version 1.32.0 \ 23 | --values kubernetes/services/librechat/embeddings-ollama.values.yaml | \ 24 | k apply -f- 25 | 26 | ## LibreChat - we're running sed for Gateway API compatibility 27 | helm template librechat --namespace aiml \ 28 | bjw-s/app-template --version 4.4.0 \ 29 | --values kubernetes/services/librechat/values.yaml | \ 30 | sed 's/v1alpha2/v1/g' | k apply -f- 31 | ``` 32 | -------------------------------------------------------------------------------- /kubernetes/services/librechat/embeddings-ollama.values.yaml: -------------------------------------------------------------------------------- 1 | name: "embeddings-ollama" 2 | enabled: true 3 | fullnameOverride: "" 4 | runtimeClassName: nvidia 5 | 6 | resources: 7 | requests: 8 | nvidia.com/gpu: "1" 9 | memory: "3Gi" 10 | limits: 11 | memory: "4Gi" 12 | cpu: "2" 13 | nvidia.com/gpu: "1" 14 | 15 | ollama: 16 | gpu: 17 | enabled: true 18 | type: nvidia 19 | models: 20 | pull: 21 | - embeddinggemma:300m 22 | run: 23 | - embeddinggemma:300m 24 | 25 | image: 26 | tag: "0.12.6" 27 | pullPolicy: "Always" 28 | 29 | extraEnv: 30 | - name: "OLLAMA_NUM_PARALLEL" 31 | value: "2" 32 | - name: "OLLAMA_FLASH_ATTENTION" 33 | value: "1" 34 | - name: "OLLAMA_MAX_LOADED_MODELS" 35 | value: "1" 36 | 37 | persistentVolume: 38 | enabled: true 39 | size: 10Gi 40 | storageClass: ceph-block-retain 41 | accessModes: 42 | - ReadWriteOnce 43 | 44 | service: 45 | annotations: 46 | gatus.home-operations.com/enabled: "true" 47 | gatus.home-operations.com/endpoint: |- 48 | name: LibreChat Ollama - Embeddings 49 | conditions: 50 | - "[STATUS] == 200" 51 | url: http://embeddings-ollama.aiml.svc.cluster.local:11434 52 | method: GET 53 | -------------------------------------------------------------------------------- /.github/scripts/helm-argo-add.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Find all Helm chart sources in Argo CD Application manifests 5 | # and add the corresponding Helm repositories if they are not already added. 6 | # This script assumes that 'helm' and 'yq' are installed and available in the PATH. 7 | crawl=$(for file in $(find kubernetes/applications -type f -maxdepth 1); do 8 | if yq e 'explode(.) | has("*chartVersion*")' "$file" > /dev/null 2>&1; then 9 | yq e 'explode(.)' "$file" | yq e '.spec.sources[]? | select(.repoURL and .chart and .targetRevision) | [.repoURL, .chart, .targetRevision] | join(",")' 10 | fi 11 | done | sort -u) 12 | 13 | echo "$crawl" | while IFS=',' read -r repo_url chart target_revision; do 14 | # Get the list of currently added Helm repo URLs 15 | repo_urls=$(helm repo list -oyaml | yq '.[].url') 16 | 17 | # Only process valid HTTP(S) URLs 18 | if [[ "$repo_url" == "https://"* ]]; then 19 | # Check if the repo URL is already added 20 | if [[ ! "$repo_urls" == *"${repo_url}"* ]]; then 21 | helm repo add "${chart}" "${repo_url}" 22 | else 23 | continue 24 | fi 25 | else # Skip over any oci:// or empty URLs 26 | continue 27 | fi 28 | done 29 | 30 | # Update Helm repos 31 | helm repo update 32 | -------------------------------------------------------------------------------- /kubernetes/applications/volsync.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: volsync 6 | namespace: argocd 7 | labels: 8 | snapshotControllerChartVersion: &snapshotControllerChartVersion 4.1.0 9 | volsyncChartVersion: &volsyncChartVersion 0.16.9 10 | spec: 11 | destination: 12 | namespace: volsync 13 | server: https://kubernetes.default.svc 14 | project: default 15 | sources: 16 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 17 | targetRevision: main 18 | ref: values 19 | - repoURL: ghcr.io/piraeusdatastore/helm-charts 20 | chart: snapshot-controller 21 | targetRevision: *snapshotControllerChartVersion 22 | helm: 23 | valueFiles: 24 | - $values/kubernetes/core/volsync/snapshot-controller.values.yaml 25 | - repoURL: ghcr.io/home-operations/charts-mirror 26 | chart: volsync-perfectra1n 27 | targetRevision: *volsyncChartVersion 28 | helm: 29 | valueFiles: 30 | - $values/kubernetes/core/volsync/volsync.values.yaml 31 | syncPolicy: 32 | automated: 33 | prune: true 34 | selfHeal: true 35 | syncOptions: 36 | - ServerSideApply=true 37 | - CreateNamespace=true 38 | -------------------------------------------------------------------------------- /kubernetes/applications/rook-ceph.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: rook-ceph 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion v1.17.7 9 | spec: 10 | destination: 11 | namespace: rook-ceph 12 | server: https://kubernetes.default.svc 13 | project: default 14 | sources: 15 | - repoURL: &repoUrl https://github.com/GoodMannersHosting/home-enterprise-labops.git 16 | targetRevision: &tg main 17 | path: kubernetes/core/rook-ceph 18 | - repoURL: *repoUrl 19 | targetRevision: *tg 20 | ref: values 21 | - repoURL: &chartURL https://charts.rook.io/release 22 | chart: &rcc rook-ceph-cluster 23 | name: *rcc 24 | targetRevision: *chartVersion 25 | helm: 26 | valueFiles: 27 | - $values/kubernetes/core/rook-ceph/cluster.values.yaml 28 | - repoURL: *chartURL 29 | chart: &rc rook-ceph 30 | name: *rc 31 | targetRevision: *chartVersion 32 | helm: 33 | valueFiles: 34 | - $values/kubernetes/core/rook-ceph/operator.values.yaml 35 | syncPolicy: 36 | automated: 37 | prune: true 38 | selfHeal: true 39 | syncOptions: 40 | - ServerSideApply=true 41 | - CreateNamespace=true 42 | -------------------------------------------------------------------------------- /kubernetes/core/monitoring/values.kps.yaml: -------------------------------------------------------------------------------- 1 | crds: 2 | enabled: true 3 | 4 | cleanPrometheusOperatorObjectNames: true 5 | 6 | grafana: 7 | envFrom: 8 | - GF_AUTH_GENERIC_OAUTH_API_URL: https://keycloak.cloud.danmanners.com/api/oidc/userinfo 9 | - GF_AUTH_GENERIC_OAUTH_AUTH_URL: https://keycloak.cloud.danmanners.com/api/oidc/authorization 10 | - GF_AUTH_GENERIC_OAUTH_CLIENT_ID: grafana 11 | - GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: https://keycloak.cloud.danmanners.com/api/oidc/token 12 | - GF_DATE_FORMATS_USE_BROWSER_LOCALE: true 13 | - GF_EXPLORE_ENABLED: true 14 | - GF_FEATURE_TOGGLES_ENABLE: publicDashboards 15 | - GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: natel-discrete-panel,pr0ps-trackmap-panel,panodata-map-panel,yesoreyeram-infinity-datasource 16 | - GF_SECURITY_ANGULAR_SUPPORT_ENABLED: true 17 | - GF_SECURITY_COOKIE_SAMESITE: grafana 18 | - GF_SERVER_ROOT_URL: https://grafana.${SECRET_PUBLIC_DOMAIN} 19 | - GF_SECURITY_HIDE_VERSION: true 20 | 21 | prometheus: 22 | prometheusSpec: 23 | retention: 14d 24 | retentionSize: 60Gi 25 | storageSpec: 26 | volumeClaimTemplate: 27 | spec: 28 | storageClassName: ceph-block-retain 29 | accessModes: ["ReadWriteOnce"] 30 | resources: 31 | requests: 32 | storage: 64Gi 33 | -------------------------------------------------------------------------------- /kubernetes/applications/cert-manager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: cert-manager 6 | namespace: argocd 7 | labels: 8 | mainChartVersion: &mainChartVersion v1.17.2 9 | webhookChartVersion: &webhookChartVersion 3.2.3 10 | spec: 11 | destination: 12 | namespace: cert-manager 13 | server: https://kubernetes.default.svc 14 | project: default 15 | sources: 16 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 17 | targetRevision: main 18 | ref: values 19 | - repoURL: https://charts.jetstack.io 20 | chart: cert-manager 21 | name: cert-manager 22 | targetRevision: *mainChartVersion 23 | helm: 24 | skipCrds: true 25 | valueFiles: 26 | - $values/kubernetes/core/cert-manager/values.cert-manager.yaml 27 | - repoURL: https://zachomedia.github.io/cert-manager-webhook-pdns 28 | chart: cert-manager-webhook-pdns 29 | name: cert-manager-webhook-pdns 30 | targetRevision: *webhookChartVersion 31 | helm: 32 | valueFiles: 33 | - $values/kubernetes/core/cert-manager/values.cert-manager-webhook-pdns.yaml 34 | syncPolicy: 35 | automated: 36 | prune: true 37 | selfHeal: true 38 | syncOptions: 39 | - ServerSideApply=true 40 | - CreateNamespace=true 41 | -------------------------------------------------------------------------------- /kubernetes/core/cert-manager/readme.md: -------------------------------------------------------------------------------- 1 | # Cert-Manager Installation 2 | 3 | ```bash 4 | # Install the CRDs 5 | kubectl apply --server-side -k kubernetes/core/cert-manager 6 | 7 | # Configure the Helm repositories 8 | helm repo add jetstack https://charts.jetstack.io 9 | helm repo add cert-manager-webhook-pdns https://zachomedia.github.io/cert-manager-webhook-pdns 10 | helm repo update 11 | 12 | # Install the Cert Manager and the PowerDNS Webhook Charts 13 | helm upgrade --install cert-manager jetstack/cert-manager \ 14 | --version v1.17.2 \ 15 | --namespace cert-manager \ 16 | --create-namespace \ 17 | --set installCRDs=false \ 18 | --values kubernetes/core/cert-manager/values.cert-manager.yaml 19 | 20 | helm upgrade --install \ 21 | cert-manager-webhook-pdns cert-manager-webhook-pdns/cert-manager-webhook-pdns \ 22 | --version 3.2.3 \ 23 | --namespace cert-manager \ 24 | --values kubernetes/core/cert-manager/values.cert-manager-webhook-pdns.yaml 25 | ``` 26 | 27 | ## Troubleshooting with PowerDNS 28 | 29 | ```bash 30 | # Get the PowerDNS API Key 31 | export powerdns_api_key=$(kubectl get secrets -n powerdns as-secrets -ojson | jq -r '.data."api-key"|@base64d') 32 | # Set the PowerDNS Zone 33 | export zone="example.com" 34 | curl -sH "X-API-Key: ${powerdns_api_key}" \ 35 | "http://172.31.0.16:8081/api/v1/servers/localhost/zones/${zone}" | \ 36 | jq -r '.rrsets[] | select(.name|startswith("whatever_hostname_goes_here"))' 37 | ``` 38 | -------------------------------------------------------------------------------- /kubernetes/services/playwright/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | defaultPodOptions: 3 | automountServiceAccountToken: true 4 | enableServiceLinks: true 5 | restartPolicy: Always 6 | securityContext: 7 | fsGroup: 1000 8 | fsGroupChangePolicy: OnRootMismatch 9 | 10 | controllers: 11 | main: 12 | enabled: true 13 | type: deployment 14 | replicas: 1 15 | revisionHistoryLimit: 2 16 | containers: 17 | core: 18 | ports: 19 | - name: ws 20 | containerPort: &port 3000 21 | protocol: TCP 22 | image: 23 | repository: mcr.microsoft.com/playwright 24 | tag: "v1.49.1-noble" 25 | pullPolicy: "IfNotPresent" 26 | command: 27 | - "/bin/sh" 28 | args: 29 | - "-c" 30 | - | 31 | npx -y playwright@1.49.1 \ 32 | run-server \ 33 | --port 3000 \ 34 | --host 0.0.0.0 35 | resources: 36 | limits: 37 | cpu: 2 38 | memory: 4Gi 39 | requests: 40 | cpu: 500m 41 | memory: 2Gi 42 | lifecycle: {} 43 | terminationMessagePath: /dev/termination-log 44 | terminationMessagePolicy: File 45 | 46 | service: 47 | core: 48 | enabled: true 49 | controller: main 50 | primary: true 51 | type: ClusterIP 52 | ports: 53 | api: 54 | enabled: true 55 | port: *port 56 | targetPort: ws 57 | protocol: TCP 58 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/coredns/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fullnameOverride: coredns 3 | replicaCount: 3 4 | k8sAppLabelOverride: kube-dns 5 | serviceAccount: 6 | create: true 7 | service: 8 | name: kube-dns 9 | clusterIP: 10.96.0.10 10 | servers: 11 | - zones: 12 | - zone: . 13 | scheme: dns:// 14 | use_tcp: true 15 | port: 53 16 | plugins: 17 | - name: errors 18 | - name: health 19 | configBlock: |- 20 | lameduck 5s 21 | - name: ready 22 | - name: log 23 | configBlock: |- 24 | class error 25 | - name: prometheus 26 | parameters: 0.0.0.0:9153 27 | - name: kubernetes 28 | parameters: cluster.local in-addr.arpa ip6.arpa 29 | configBlock: |- 30 | pods insecure 31 | fallthrough in-addr.arpa ip6.arpa 32 | - name: forward 33 | parameters: . /etc/resolv.conf 34 | - name: cache 35 | parameters: 30 36 | - name: loop 37 | - name: reload 38 | - name: loadbalance 39 | affinity: 40 | nodeAffinity: 41 | requiredDuringSchedulingIgnoredDuringExecution: 42 | nodeSelectorTerms: 43 | - matchExpressions: 44 | - key: node-role.kubernetes.io/control-plane 45 | operator: Exists 46 | tolerations: 47 | - key: CriticalAddonsOnly 48 | operator: Exists 49 | - key: node-role.kubernetes.io/control-plane 50 | operator: Exists 51 | effect: NoSchedule 52 | topologySpreadConstraints: 53 | - maxSkew: 1 54 | topologyKey: kubernetes.io/hostname 55 | whenUnsatisfiable: DoNotSchedule 56 | labelSelector: 57 | matchLabels: 58 | app.kubernetes.io/instance: coredns 59 | -------------------------------------------------------------------------------- /kubernetes/services/iperf3/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | defaultPodOptions: 3 | automountServiceAccountToken: false 4 | enableServiceLinks: true 5 | restartPolicy: Always 6 | 7 | controllers: 8 | main: 9 | enabled: true 10 | type: deployment 11 | replicas: 1 12 | revisionHistoryLimit: 2 13 | containers: 14 | iperf: 15 | ports: 16 | - name: iperf-tcp 17 | containerPort: 5201 18 | protocol: TCP 19 | - name: iperf-udp 20 | containerPort: 5201 21 | protocol: UDP 22 | image: 23 | repository: harbor.cloud.danmanners.com/library/networkstatic/iperf3 24 | tag: "latest" 25 | pullPolicy: "IfNotPresent" 26 | securityContext: 27 | allowPrivilegeEscalation: false 28 | args: 29 | - "--server" 30 | resources: 31 | limits: 32 | cpu: 4 33 | memory: 8Gi 34 | requests: 35 | cpu: 250m 36 | memory: 1Gi 37 | lifecycle: {} 38 | terminationMessagePath: /dev/termination-log 39 | terminationMessagePolicy: File 40 | 41 | service: 42 | core: 43 | enabled: true 44 | controller: main 45 | primary: true 46 | type: LoadBalancer 47 | ports: 48 | tcp: 49 | enabled: true 50 | port: 5201 51 | targetPort: iperf-tcp 52 | protocol: TCP 53 | udp: 54 | enabled: true 55 | port: 5201 56 | targetPort: iperf-udp 57 | protocol: UDP 58 | 59 | rawResources: 60 | namespace: 61 | enabled: true 62 | apiVersion: v1 63 | kind: Namespace 64 | spec: {} 65 | -------------------------------------------------------------------------------- /kubernetes/applications/gh-runners.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: gh-runners 6 | namespace: argocd 7 | labels: 8 | controllerChartVersion: &chartVersion 0.12.1 9 | spec: 10 | ignoreDifferences: 11 | - &ignore 12 | group: apiextensions.k8s.io 13 | kind: CustomResourceDefinition 14 | name: autoscalingrunnersets.actions.github.com 15 | jsonPointers: 16 | - /spec/preserveUnknownFields 17 | - <<: *ignore 18 | name: autoscalinglisteners.actions.github.com 19 | - <<: *ignore 20 | name: ephemeralrunners.actions.github.com 21 | - <<: *ignore 22 | name: ephemeralrunnersets.actions.github.com 23 | destination: 24 | namespace: github 25 | server: https://kubernetes.default.svc 26 | project: default 27 | sources: 28 | - repoURL: &url https://github.com/GoodMannersHosting/home-enterprise-labops.git 29 | targetRevision: &branch main 30 | path: kubernetes/services/github-action-runners/runners 31 | kustomize: 32 | labels: 33 | - includeSelectors: true 34 | pairs: 35 | app.kubernetes.io/version: *chartVersion 36 | - repoURL: *url 37 | targetRevision: *branch 38 | ref: values 39 | - name: controller 40 | repoURL: ghcr.io/actions/actions-runner-controller-charts 41 | chart: gha-runner-scale-set-controller 42 | targetRevision: *chartVersion 43 | helm: 44 | valueFiles: 45 | - $values/kubernetes/services/github-action-runners/controller/values.yaml 46 | syncPolicy: 47 | automated: 48 | prune: true 49 | selfHeal: true 50 | syncOptions: 51 | - ServerSideApply=true 52 | - CreateNamespace=true 53 | -------------------------------------------------------------------------------- /kubernetes/services/nvdp/values.yaml: -------------------------------------------------------------------------------- 1 | affinity: 2 | nodeAffinity: 3 | requiredDuringSchedulingIgnoredDuringExecution: 4 | nodeSelectorTerms: 5 | - matchExpressions: 6 | # On discrete-GPU based systems NFD adds the following label where 10de is the NVIDIA PCI vendor ID 7 | - key: feature.node.kubernetes.io/pci-10de.present 8 | operator: In 9 | values: 10 | - "true" 11 | config: 12 | map: 13 | default: |- 14 | version: v1 15 | flags: 16 | migStrategy: "none" 17 | failOnInitError: true 18 | nvidiaDriverRoot: "/" 19 | nvidiaDevRoot: "/" 20 | plugin: 21 | passDeviceSpecs: true 22 | deviceListStrategy: "envvar" 23 | deviceIDStrategy: "uuid" 24 | gfd: 25 | oneshot: false 26 | noTimestamp: false 27 | outputFile: "/etc/kubernetes/node-feature-discovery/features.d/gfd" 28 | sleepInterval: "60s" 29 | sharing: 30 | timeSlicing: 31 | resources: 32 | - name: "nvidia.com/gpu" 33 | replicas: 6 34 | resources: 35 | gpus: 36 | - pattern: "*" 37 | name: "nvidia.com/gpu" 38 | mig-single: |- 39 | version: v1 40 | flags: 41 | migStrategy: single 42 | mig-mixed: |- 43 | version: v1 44 | flags: 45 | migStrategy: mixed 46 | # Default config name within the ConfigMap 47 | default: "default" 48 | # List of fallback strategies to attempt if no config is selected and no default is provided 49 | fallbackStrategies: ["named", "single"] 50 | gfd: 51 | enabled: true 52 | nfd: 53 | enabled: true 54 | runtimeClassName: nvidia 55 | nodeSelector: 56 | feature.node.kubernetes.io/pci-10de.present: "true" 57 | -------------------------------------------------------------------------------- /kubernetes/core/forgejo/secret.forgejo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | name: forgejo-database-credentials 6 | namespace: forgejo 7 | spec: 8 | encryptedData: 9 | password: AgAx18yPS85xVSGCb7XHzIR0q8EH+a1P0taFF/DVH9KKVEC1IPtzAITmGHCGMfhiDwELWhPnQq3HXRTKoyeSXTgqfjYIic5899tAjHM9X62F9hKIgRyCXiWJ6LZEk+hjL6Bw/D9oubHsSM9lTjK10JoTb0cO/6UZpkg2OKcrbjS/Y/BBRDehfw9zl4PnCTtdP/2B+cA0kDGFFSRuRVbT3BmvYmmHPX8CtfrbKr8uqJ5r8YtciULRx/VndgcXHrZhGOYCjwSgEMlzF/UVH1uqrh5HNDJAnkjSpKsCVkGzCuIes75MtJfJ8KoAvN8vdJgTydJnky4gfUYFB84/gYbho2V+kwT3Lin11gsTg8By5MxesLDAxPgaEH8m1xUAtJ43rWZEsNduph/El9asayQGhcRWy4QNvDAC7V2KkjxHqO1I9qa8pOz2Wa4/8LrI4t91mBDF4Qub1CDv68CF8eh7hq0IvJaYHQ+k45imEAypx3dleJt/SwQ8pgiWZEIXpk7O5M+Pcxc/EqGLvd71YIVA3h5VIMdt+dhcMYJzXYN7N3Uo6f/e8pjzatGP9auoQYmYGbyUE4XSeRrReh/YTbpNbWvFGqwVOSvqsbzYUCn0FXXCXaEx1xzLm2k0TpZIkAQR1mL3x/xAL6r6Aw1u0xpzOvfwo/OFLqJqBrsblsUQ+MNBO6B79CJ3P8wJu7OCb/eno1KCQ+fKhIjzo7fb+0bJ4Uki2wMgcGXpDYXBBTVdaD9wJ5wIlGA= 10 | username: AgAJM/g5hzCJ+i7shGC50wc6/FxwEhY5awNDZl4A5XH+6O1tdCofD6DcBPuJ1n2WP8NUs5Gfzh5XZqnmXPuQoxr+6dp0cpe7n3W36KJYhLrZt6055ExuPgiP0eyO/KWd78P55mafvKdV4jr+lMBJ2JXSAwP5g53oU1pG56HJ5a1/sijgMlw4xIty5CzHWl/oyQtBloVQ8VZ141IP+qCCRVhKTEIW4Hagz9wXoq7E/HGQ6FKb0eiY6BLgOQ98qCRRs71fB9tS4iUdGrH77Bm0vWhLcBva/S+O6TrV+rrJl1Dboe9vzxFxF7x+DC+535LlLcXz0T6UGgF5bGiVolziQjeXeXwY8ukTn+P4Sv3S4YxtmsXd4PrkH8K+AVxL66lO4Sx3CleKQI+TcIBCTn8fRtmQqA6gE7V1yIbVpxdLdTHkF5WNCLaRMNLRunj8yNT6b0+vT2skNrJ0Wckhmhv1lVZbNg3vZOVIF7OsW2H5wr5x64BksiTS2INnUJSgssTpZiBPRv7wy+zhSxD2q0j0DjPGAldJuH93FeMX7sfmYEYmFWa59uw19UPbnk2acT+OEwin72GBkix88xV8n6S0bN7kIKq2/Rdb5/wSteAF2SShmEb8/vzCX3BuelJ0lxR3jiNIOnowg3Pr5fDqAvtFTfyJzrp6+ZbErXEL94rLnX+SvNjnt53xHUwN3PTzDDWJKbnSs03h+Gor 11 | template: 12 | metadata: 13 | name: forgejo-database-credentials 14 | namespace: forgejo 15 | type: Opaque 16 | -------------------------------------------------------------------------------- /kubernetes/services/docling/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | defaultPodOptions: 3 | automountServiceAccountToken: false 4 | enableServiceLinks: false 5 | runtimeClassName: nvidia 6 | restartPolicy: Always 7 | securityContext: 8 | fsGroup: 1000 9 | fsGroupChangePolicy: OnRootMismatch 10 | 11 | controllers: 12 | main: 13 | enabled: true 14 | type: deployment 15 | replicas: 1 16 | revisionHistoryLimit: 2 17 | containers: 18 | core: 19 | ports: 20 | - name: http 21 | containerPort: 5001 22 | protocol: TCP 23 | image: 24 | repository: ghcr.io/docling-project/docling-serve-cu128 25 | tag: "v1.3.1" 26 | pullPolicy: "IfNotPresent" 27 | securityContext: 28 | allowPrivilegeEscalation: false 29 | env: 30 | - name: DOCLING_SERVE_ENABLE_UI 31 | value: "true" 32 | resources: 33 | limits: 34 | cpu: 4 35 | memory: 8Gi 36 | nvidia.com/gpu: "1" 37 | requests: 38 | cpu: 250m 39 | memory: 1Gi 40 | nvidia.com/gpu: "1" 41 | lifecycle: {} 42 | terminationMessagePath: /dev/termination-log 43 | terminationMessagePolicy: File 44 | 45 | service: 46 | core: 47 | enabled: true 48 | controller: main 49 | primary: true 50 | type: ClusterIP 51 | ports: 52 | http: 53 | enabled: true 54 | port: 5001 55 | targetPort: http 56 | protocol: TCP 57 | 58 | persistence: 59 | data: 60 | enabled: true 61 | type: persistentVolumeClaim 62 | storageClass: ceph-block-retain 63 | accessMode: ReadWriteOnce 64 | size: 10Gi 65 | retain: true 66 | globalMounts: 67 | - path: /modelcache 68 | readOnly: false 69 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/cilium/values.yaml: -------------------------------------------------------------------------------- 1 | autoDirectNodeRoutes: true 2 | bandwidthManager: 3 | enabled: true 4 | bbr: true 5 | bpf: 6 | datapathMode: netkit 7 | masquerade: false 8 | preallocateMaps: true 9 | bpfClockProbe: true 10 | bgpControlPlane: 11 | enabled: true 12 | cni: 13 | exclusive: false 14 | cgroup: 15 | automount: 16 | enabled: false 17 | hostRoot: /sys/fs/cgroup 18 | cluster: 19 | id: 1 20 | name: capi-core 21 | devices: e+ 22 | endpointRoutes: 23 | enabled: true 24 | envoy: 25 | enabled: true 26 | envoyConfig: 27 | enabled: false 28 | hubble: 29 | enabled: false 30 | ipam: 31 | mode: kubernetes 32 | ipv4NativeRoutingCIDR: 10.244.0.0/16 33 | k8sServiceHost: localhost 34 | k8sServicePort: 7445 35 | kubeProxyReplacement: true 36 | kubeProxyReplacementHealthzBindAddr: 0.0.0.0:10256 37 | l2announcements: 38 | enabled: true 39 | loadBalancer: 40 | acceleration: best-effort 41 | algorithm: maglev 42 | mode: dsr 43 | localRedirectPolicy: true 44 | operator: 45 | replicas: 2 46 | rollOutPods: true 47 | prometheus: 48 | enabled: false 49 | serviceMonitor: 50 | enabled: false 51 | dashboards: 52 | enabled: true 53 | prometheus: 54 | enabled: false 55 | dashboards: 56 | enabled: false 57 | rollOutCiliumPods: true 58 | routingMode: native 59 | securityContext: 60 | capabilities: 61 | ciliumAgent: 62 | - CHOWN 63 | - KILL 64 | - NET_ADMIN 65 | - NET_RAW 66 | - IPC_LOCK 67 | - SYS_ADMIN 68 | - SYS_RESOURCE 69 | - DAC_OVERRIDE 70 | - FOWNER 71 | - SETGID 72 | - SETUID 73 | - PERFMON 74 | - BPF 75 | cleanCiliumState: 76 | - NET_ADMIN 77 | - SYS_ADMIN 78 | - SYS_RESOURCE 79 | 80 | gatewayAPI: 81 | enabled: true 82 | gatewayClass: 83 | create: "true" 84 | 85 | # socketLB: 86 | # hostNamespaceOnly: true 87 | -------------------------------------------------------------------------------- /kubernetes/services/palworld/secrets.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: palworld-secrets 7 | namespace: palworld 8 | spec: 9 | encryptedData: 10 | ADMIN_PASSWORD: AgAMAxokkLck3IsdYjwvPzVoQtow5LjVKmzGZ8PTo4sfoeTDGTFMcRRerFNYExlTDKPrHuJsfeyyqQFc1T0fWw5KQk8g72mQT1yezUTDCmVZJtXgheaYbV3iNXvJ41hTs7aKQ95AF+u2ZJPTIG0VJI9CitKpuJFVhQoEW/1Vr+4obr4oRFuPo6tHGIQrVfzuvm2bTgKkdMqiRusFRsQABYF05fmTaZTCXaE67xAjsa0EIHZz9ceLWsE9SCmI1gu3DlL1HFCufzC/8jIxcaB7ja8WvgQBNI5bZhWXySL/Y/NHsvptgDeefvJZ5Xo4V930HzK85ZTy0Zsqjh7yQ3p0W6oKmYKWGqssRQb3nCoW8V70GdZ6ue3nCCjRoWi4qY9IJUHpuq0dRCTIuw/m58yKMxUhRNfCbdPeYwbZ4Bti3uN0pw9ivrOJebW5OySKTGP6pEwvGpIg9GkbqO8MikqZ7GTsL6KIfZtp3CThjCgzF/OAQ7wOahbNlhCbhlm9HkWHqRm3j3hEIriHncp3SnwGC5zTTPpcScn9bDDu0JjzR9Yt4BiPz5FgymSu7KAFEzQGvEqk/6NOjOnRdMAVBG8uIfSW/UNFws4B5vuo0IQDNKBYDq4muQ4AZ+s/cJc5b9PaDkq+2hovWQn2VzpERpOwwmGUJ5qwwMxJrdwkBl4yTBwgh5SIzUiFGxvpik2HtLzXIHUbKqYtGquyNJH6pLEk3ZUrFuwYIYagkElYNS3wguj53Q== 11 | SERVER_PASSWORD: AgBLaUTrPuIVFI9w4KLz7/plzuSblFD1c7qaWlOatpoWfZqoca6vJQhLJ5cdSOgkLD+/dbw6TSd9sP7S3V2+HGVm+nCuqsxro0CSjDz0+gPc03KzHQo43TNWieFB/3KDUyo+IxX607wJ75tzP49ygXptYO8e2cP4VxDy51FI4ow/oZnqwH2yeLwTpGnSToj0inTAqp+kjffgzYMROZ6ayqTAsxp8MJdmmIMmmZw5/fLuzHATLJ5kAhtHFwd87Cw2l8dhEORgGgI4WqEFdvo1plfCEa+5IpBd0VJbMwJtAcmKx+ydFHuvDfd07duoOTZhfsd+czQrsafRRZQ91Wnc4ewn+VM8+Ro2M/bQcxQhR/dWJHrCqulfcK1skRkkh1w/anEyo+Vqyu8QSfYoI2mEBCrlWNuoiBzCxtY9zIinekRW3ncIee/mBISYhtWllSS+abs9JnxtIr0u6FM7KD6Yg2L4TQdRMYFVGLx3sERq2wWyh2/ULC3CmGMtqnvVnpyT82+dQVAhGX9Xg6g5Xr40zXYLMwHcxhczWT1eZMLvhHRyBVXnv9PZd4pN/gTSQeMQ/VvLA8SFKhUytwyjPwtgjSqXdS3Ssa+feBzcGdJaEj2BV4MQg3r3okIOPxrtbqMc52RO4TiiInIE0FSViCuth6eBVbJfYPUgbkWF1822LdLuS06adBpqVZwWVEHD49ePAU0oP2OLLy+kXHc= 12 | template: 13 | metadata: 14 | creationTimestamp: null 15 | name: palworld-secrets 16 | namespace: palworld 17 | type: Opaque 18 | -------------------------------------------------------------------------------- /keys/gen-aws-iam-ra.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | # Set variables 4 | CA_KEY_NAME="ca.key" 5 | CA_CERT_NAME="ca.crt" 6 | CSR_NAME="cert.csr" 7 | CSR_KEY_NAME="cert.key" 8 | CSR_CERT_NAME="cert.crt" 9 | CA_VALIDITY_DAYS=3650 10 | CSR_VALIDITY_DAYS=365 11 | KEY_SIZE=4096 12 | CSR_SUBJECT="/OU=palworld-backups" 13 | 14 | # # Generate CA private key 15 | # openssl genrsa -out $CA_KEY_NAME $KEY_SIZE 16 | openssl ecparam -genkey -name secp384r1 -out $CA_KEY_NAME 17 | echo "Generated CA private key: $CA_KEY_NAME" 18 | 19 | # # Create CA certificate 20 | openssl req -new -x509 -nodes -sha256 -key $CA_KEY_NAME \ 21 | -out $CA_CERT_NAME -days $CA_VALIDITY_DAYS \ 22 | -subj "/CN=CA Certificate Authority/OU=IAM Roles Anywhere/O=GoodMannersHosting" \ 23 | -addext="keyUsage=keyCertSign,cRLSign,digitalSignature" \ 24 | -addext="basicConstraints=CA:TRUE" \ 25 | -addext="subjectKeyIdentifier=hash" \ 26 | -addext="authorityKeyIdentifier=keyid:always" 27 | echo "Generated CA certificate: $CA_CERT_NAME" 28 | 29 | # Generate CSR for trust anchor 30 | openssl req -new -sha512 -nodes -keyout $CSR_KEY_NAME \ 31 | -out $CSR_NAME -subj "$CSR_SUBJECT" \ 32 | -addext="keyUsage=critical,digitalSignature" \ 33 | -addext="basicConstraints=critical,CA:FALSE" 34 | echo "Generated CSR for trust anchor: $CSR_NAME" 35 | 36 | # Sign CSR with CA 37 | openssl x509 -req -in $CSR_NAME -CA $CA_CERT_NAME \ 38 | -CAkey $CA_KEY_NAME -out $CSR_CERT_NAME \ 39 | -days $CSR_VALIDITY_DAYS \ 40 | -extfile <(echo -e "keyUsage = critical,digitalSignature\nbasicConstraints = critical,CA:FALSE") 41 | echo "Signed CSR with CA to generate trust anchor certificate: $CSR_CERT_NAME" 42 | 43 | # Output instructions 44 | echo "Trust anchor configuration complete:" 45 | echo "CA private key: $CA_KEY_NAME" 46 | echo "CA certificate: $CA_CERT_NAME" 47 | echo "CSR: $CSR_NAME" 48 | echo "Trust anchor certificate: $CSR_CERT_NAME" 49 | -------------------------------------------------------------------------------- /kubernetes/services/tabbyml/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | defaultPodOptions: 3 | automountServiceAccountToken: false 4 | enableServiceLinks: false 5 | runtimeClassName: nvidia 6 | restartPolicy: Always 7 | securityContext: 8 | fsGroup: 1000 9 | fsGroupChangePolicy: OnRootMismatch 10 | 11 | controllers: 12 | tabby: 13 | enabled: true 14 | type: deployment 15 | replicas: 1 16 | revisionHistoryLimit: 2 17 | containers: 18 | core: 19 | ports: 20 | - name: http 21 | containerPort: 8080 22 | protocol: TCP 23 | image: 24 | repository: registry.tabbyml.com/tabbyml/tabby 25 | tag: "0.31.1" 26 | pullPolicy: "IfNotPresent" 27 | securityContext: 28 | allowPrivilegeEscalation: false 29 | args: 30 | - "serve" 31 | - "--model=Qwen2.5-Coder-14B" 32 | - "--chat-model=Qwen2.5-Coder-1.5B-Instruct" 33 | - "--device=cuda" 34 | resources: 35 | limits: 36 | cpu: 6 37 | memory: 16Gi 38 | nvidia.com/gpu: "1" 39 | requests: 40 | cpu: 250m 41 | memory: 8Gi 42 | nvidia.com/gpu: "1" 43 | lifecycle: {} 44 | terminationMessagePath: /dev/termination-log 45 | terminationMessagePolicy: File 46 | 47 | service: 48 | core: 49 | enabled: true 50 | controller: tabby 51 | primary: true 52 | type: LoadBalancer 53 | ports: 54 | http: 55 | enabled: true 56 | port: 80 57 | targetPort: http 58 | protocol: TCP 59 | 60 | persistence: 61 | data: 62 | enabled: true 63 | type: persistentVolumeClaim 64 | storageClass: ceph-block-retain 65 | accessMode: ReadWriteOnce 66 | size: 60Gi 67 | retain: true 68 | globalMounts: 69 | - path: /data 70 | readOnly: false 71 | -------------------------------------------------------------------------------- /kubernetes/core/database/secret.database.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: database-superuser 7 | namespace: database 8 | spec: 9 | encryptedData: 10 | password: AgACFD51iWnhHVsHovHa4ZZHGgGafLZoR8KRqvhHxL+brsSc06rAc283KACuKVzsU2yJVq91jyFFBigtYrSgAmY7nTokE+AuFkUdeU47WGuoaz7wIBw6XpiiLtR6k0jdhXk9pupsCuii1VCeqSeTPbuqyiLSxzzJeVW+3eUW4Gi0vwm947xJzoJW4T4CiV5/DFuuT5PkCuB3G+ZTU56su1SSpRShNzeU5fuyPI2QgB0agKC3GOq2zXFALBlXhj3Uk9maktEQbxrsHXFWNbc6swA+IdaiKWt/HOgdgXDgKx12s8QaqGDFaBX3T2bpIpgXDO/MVn/uw5LZfSC54KrLdn0CVAABqLtDc8Qbb0/QPPMSYKfg1/z3Xcav0nFUvHkA1QprS1UBKL/deh880UtCHAs5Cj26j5Ipf6T3idzUK1p5NLBg+QwYKZdOBnToZsEixycTvorKmCdASq70M/n50enXsm1JLDF+rrhtn4zEK+GTPgTeORSToAhVCPaet7YgdmgvBMHfisVpIOVFvFDvpcXqarZeS5OMGwVbhquQ73NFHdLwz1H5SyQ9Hyahklcpp/I/wETtMQiG737yHyhurg1/vpjVqYKbz5171Q6aoaNV+fIr7BbfvqlP+lj0ugCz/Mer9LLYF7LkcE+ZvCuSTK8se0cd1EaHlpdKyQjVfDvZgWlUbPZElC9Gz711+gZSpCDOBV31sY5s/HDJ1zxHynaGWDpa3K8eFJrWCOfHuVXcCIM= 11 | username: AgCF2pb/a7ZcAnW2/IMkzaMCP+A1RkWNcQ1DaWfttVacWEsFAUa7VGksZJ1B8VDWFwoAnMais5u9bci6vtXUjHgXS+I67EZbqFo7bvdp3gzENRfQLUJW3LR76Ud2kM4Pi6xXKHVGC6vf1XAOsIogmX/6KY5v/LMdktPWiJGxUNiLYRUbhRcNEummTHoPI91nQw3jPR/+x/VO9/nHZH44slZ0/2gXgT4CdJrX7DVyjLJcNTKNDV0ZM+cM0lZrg4tXFuw6bGzLjI2zMa0cgAqr6vFd1G5Mamhty5VWpn4E5Y2ufk0z/wXv8FhEVcAOpqM5DP9CEJQg5TowfKYt4aGy70sFp4Y73ttRYnf2uv8N/4XELNcvVoUiAkfOaE3oLPHboGFC5oufcrfqS3XrOLq23W0D9PcuyXYJozWfu4zEfY8Qs7myw5zTCXTp3+TPNxcOxyN5igBTT1ZC4k84T0YvKU2MraCm0lfMFlhGLOkHTByVbFfurqyNn8GHZqEnUwAVMSluGpGDC+voikTY0IM1HFpQJRXPWufz7mMjKpgVdEXEQ4uHNR7ln7X8tHVJqPxATQIm7M5I99JW0ZbxWKjIrxv2wG9YLa28gQXsnxJxWyt0EXf2shlS4+DFhSqiId82V9q1x34t+dUTWS+BgmO3d1D6xUC7YSyZrb5Kv45Nni1aG6l2YYH7DAZsM1od42640oMt3rW3CoYciQ== 12 | template: 13 | metadata: 14 | annotations: 15 | reflector.v1.k8s.emberstack.com/reflection-allowed: "true" 16 | creationTimestamp: null 17 | name: database-superuser 18 | namespace: database 19 | type: Opaque 20 | -------------------------------------------------------------------------------- /keys/sealed-secret.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFQTCCAymgAwIBAgIUQ5MBXI2Zlcr53VEgbhxkskYs/REwDQYJKoZIhvcNAQEL 3 | BQAwMDEWMBQGA1UEAwwNc2VhbGVkLXNlY3JldDEWMBQGA1UECgwNc2VhbGVkLXNl 4 | Y3JldDAeFw0yNTA0MTQwNTAzMDRaFw0zNTA0MTIwNTAzMDRaMDAxFjAUBgNVBAMM 5 | DXNlYWxlZC1zZWNyZXQxFjAUBgNVBAoMDXNlYWxlZC1zZWNyZXQwggIiMA0GCSqG 6 | SIb3DQEBAQUAA4ICDwAwggIKAoICAQCT11+6JRHmWB5kk5+42IOC+llAgROtX7Jx 7 | pISREKFZx5Dw7h6YkT8NFzPkK7fP3ZaKvFjXVwZw4ojErW6NkXRN3Kt0LWdm6Lo0 8 | pkeq4TV4TRZe/3rKfPqJdOMz1wvS5nIXtNuTHPxgMpINjqr53BQLOWH1wFvRa6Bm 9 | 5hizPgdacfegEDHfrpOJTNv2X4iPFz6w7Bm70XwWhrMXC3a/qUWrGFSw5+UVE9wP 10 | 3pzY3pib/eEgs4NcJ2Gphj6ho3feZjQVHilRycUUQ1LqsE2ESyDau++CjRDU0bMH 11 | JmRDDU59e5zl1O9+F1YNjgy5la1gBtavjwTdsvF2ibe5Um56zZ4o1oXD3153onJd 12 | fN8GwgH8JPxmY4vR5uoB8AFmGDQqOuJF0FB2RJJzQMoK/fRjpNrHDT4ivKi6AZqF 13 | 6bX7Zc8VKhT4TvNHIu92TKcHRtMcjl+i07J7h8mkQkoFHlUU8hDRLWTEkrGlIGEu 14 | RdiE4HWv22IDoca61OdfNSFlz3o2ZxA3eJATS99aT35D9esQ/RTKPeK2hvh00WGt 15 | ot9MxdtSS16oHOxDmYxXAKfdhHhEtdac693ffElk+YFOgL0OH3ejZ/mpj/k1PkoL 16 | UmYqeYqHml4lzjn/IrGzmGTANn0K8fEeQy/kZeg53PeKkXeQ1AD53cfJ5WE542dq 17 | 6qmaKzwwUwIDAQABo1MwUTAdBgNVHQ4EFgQUy0kz2T3J9quLrHFECpz4vqspDlgw 18 | HwYDVR0jBBgwFoAUy0kz2T3J9quLrHFECpz4vqspDlgwDwYDVR0TAQH/BAUwAwEB 19 | /zANBgkqhkiG9w0BAQsFAAOCAgEANFrUMVn/D4XpOFbu8W6F1df63ytzYHZ1InMu 20 | rGsj7P316uL/Hocd857ZaRKUeXxds0lH8CFccVuDWqALh9+4XDq6q09b43Jm9ihw 21 | q6xJSQwh/gTa8j3748pkn5cKUi8nN+ow6wsSE1SIVzJljEtcU9DFjUVk0haD//A2 22 | YF0L1/FHJsE3mCWZXRmatXYxufgrRD+dylrlB4aetX2SkKP1zAc6tZPuAfGMTGZV 23 | lpdlXMmohx717OGLtkcBnbHysY8s3GLXLmXqXKnK77cRWOJNJlItlrot5f4BuZ98 24 | E/1/HPWp2bBAu6QfxiI6EQm9qhLqHRpvgGiRg+/h3Id6q13h5ZczfTJAq/ZQTtKM 25 | mt6+I5Viw+H7JFfozBkqlfGxfidTjWA+V1QUaqYEEH8etkgrAVuBr1JyHQ+zSJ/p 26 | axGeZlVldPTBVNGQocwAZl0UlNO4utxlJguAL4C5MMk/dx3liAmsbao62xNJ8Rrt 27 | 5wZf0u43NSOD4cf5aatfvISpJR8tj2zBDCzajwpPgEa6kFnc41FxLM4YayGh+OMh 28 | 2KPUha42JjzZmI/cJuNMUNj48Jm2hvRZL08x9o8yGvC1MaWwoCIJ/XNdSZNEWayC 29 | vr3Fmpw/Pv4geKAvWFLtCFqr9WAcBM3kARwnBFA3+sMDODqIF4iPJl2MeYMgtfZR 30 | 1urVcRc= 31 | -----END CERTIFICATE----- 32 | -------------------------------------------------------------------------------- /kubernetes/services/github-action-runners/runners/rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Source: gha-runner-scale-set/templates/manager_role.yaml 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: Role 5 | metadata: 6 | name: shr-gha-rs-manager 7 | namespace: github 8 | labels: 9 | actions.github.com/scale-set-name: shr 10 | actions.github.com/scale-set-namespace: github 11 | app.kubernetes.io/component: manager-role 12 | finalizers: 13 | - actions.github.com/cleanup-protection 14 | rules: 15 | - apiGroups: 16 | - "" 17 | resources: 18 | - pods 19 | verbs: 20 | - create 21 | - delete 22 | - get 23 | - apiGroups: 24 | - "" 25 | resources: 26 | - pods/status 27 | verbs: 28 | - get 29 | - apiGroups: 30 | - "" 31 | resources: 32 | - secrets 33 | verbs: 34 | - create 35 | - delete 36 | - get 37 | - list 38 | - patch 39 | - update 40 | - apiGroups: 41 | - "" 42 | resources: 43 | - serviceaccounts 44 | verbs: 45 | - create 46 | - delete 47 | - get 48 | - list 49 | - patch 50 | - update 51 | - apiGroups: 52 | - rbac.authorization.k8s.io 53 | resources: 54 | - rolebindings 55 | verbs: 56 | - create 57 | - delete 58 | - get 59 | - patch 60 | - update 61 | - apiGroups: 62 | - rbac.authorization.k8s.io 63 | resources: 64 | - roles 65 | verbs: 66 | - create 67 | - delete 68 | - get 69 | - patch 70 | - update 71 | --- 72 | # Source: gha-runner-scale-set/templates/manager_role_binding.yaml 73 | apiVersion: rbac.authorization.k8s.io/v1 74 | kind: RoleBinding 75 | metadata: 76 | name: shr-gha-rs-manager 77 | namespace: github 78 | labels: 79 | actions.github.com/scale-set-name: shr 80 | actions.github.com/scale-set-namespace: github 81 | app.kubernetes.io/component: manager-role-binding 82 | finalizers: 83 | - actions.github.com/cleanup-protection 84 | roleRef: 85 | apiGroup: rbac.authorization.k8s.io 86 | kind: Role 87 | name: shr-gha-rs-manager 88 | subjects: 89 | - kind: ServiceAccount 90 | name: arc 91 | namespace: github 92 | -------------------------------------------------------------------------------- /kubernetes/projects/wander-winter/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: oidc:wander-winter 5 | namespace: wander-winter 6 | rules: 7 | - apiGroups: ["*"] 8 | resources: ["*"] 9 | verbs: ["*"] 10 | resourceNames: [] 11 | # Exclude ResourceQuotas, ceph.rook.io, and appproject.argoproj.io using separate deny rules (not natively supported in Kubernetes RBAC). 12 | # You must ensure there are no other Roles granting access to these resources. 13 | - apiGroups: [""] 14 | resources: ["resourcequotas"] 15 | verbs: ["list", "get", "watch"] 16 | - apiGroups: ["ceph.rook.io"] 17 | resources: ["*"] 18 | verbs: ["list", "get", "watch"] 19 | - apiGroups: ["appproject.argoproj.io"] 20 | resources: ["*"] 21 | verbs: ["list", "get", "watch"] 22 | --- 23 | apiVersion: rbac.authorization.k8s.io/v1 24 | kind: RoleBinding 25 | metadata: 26 | name: group:oidc:wander-winter 27 | namespace: wander-winter 28 | subjects: 29 | - kind: Group 30 | name: oidc:/wander-winter 31 | apiGroup: rbac.authorization.k8s.io 32 | roleRef: 33 | kind: Role 34 | name: oidc:wander-winter 35 | apiGroup: rbac.authorization.k8s.io 36 | --- 37 | apiVersion: rbac.authorization.k8s.io/v1 38 | kind: ClusterRole 39 | metadata: 40 | name: oidc:wander-winter:restrictedclusteraccess 41 | rules: 42 | - apiGroups: ["storage.k8s.io"] 43 | resources: ["storageclasses"] 44 | verbs: ["list", "get", "watch"] 45 | - apiGroups: [""] 46 | resources: 47 | ["namespaces", "persistentvolumes", "nodes", "persistentvolumeclaims"] 48 | verbs: ["list", "get", "watch"] 49 | --- 50 | apiVersion: rbac.authorization.k8s.io/v1 51 | kind: ClusterRoleBinding 52 | metadata: 53 | name: group:oidc:wander-winter:restrictedclusteraccess 54 | subjects: 55 | - kind: Group 56 | name: oidc:/wander-winter 57 | apiGroup: rbac.authorization.k8s.io 58 | roleRef: 59 | kind: ClusterRole 60 | name: oidc:wander-winter:restrictedclusteraccess 61 | apiGroup: rbac.authorization.k8s.io 62 | -------------------------------------------------------------------------------- /kubernetes/projects/danger-million/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: oidc:danger-million 5 | namespace: danger-million 6 | rules: 7 | - apiGroups: ["*"] 8 | resources: ["*"] 9 | verbs: ["*"] 10 | resourceNames: [] 11 | # Exclude ResourceQuotas, ceph.rook.io, and appproject.argoproj.io using separate deny rules (not natively supported in Kubernetes RBAC). 12 | # You must ensure there are no other Roles granting access to these resources. 13 | - apiGroups: [""] 14 | resources: ["resourcequotas"] 15 | verbs: ["list", "get", "watch"] 16 | - apiGroups: ["ceph.rook.io"] 17 | resources: ["*"] 18 | verbs: ["list", "get", "watch"] 19 | - apiGroups: ["appproject.argoproj.io"] 20 | resources: ["*"] 21 | verbs: ["list", "get", "watch"] 22 | --- 23 | apiVersion: rbac.authorization.k8s.io/v1 24 | kind: RoleBinding 25 | metadata: 26 | name: group:oidc:danger-million 27 | namespace: danger-million 28 | subjects: 29 | - kind: Group 30 | name: oidc:/danger-million 31 | apiGroup: rbac.authorization.k8s.io 32 | roleRef: 33 | kind: Role 34 | name: oidc:danger-million 35 | apiGroup: rbac.authorization.k8s.io 36 | --- 37 | apiVersion: rbac.authorization.k8s.io/v1 38 | kind: ClusterRole 39 | metadata: 40 | name: oidc:danger-million:restrictedclusteraccess 41 | rules: 42 | - apiGroups: ["storage.k8s.io"] 43 | resources: ["storageclasses"] 44 | verbs: ["list", "get", "watch"] 45 | - apiGroups: [""] 46 | resources: 47 | ["namespaces", "persistentvolumes", "nodes", "persistentvolumeclaims"] 48 | verbs: ["list", "get", "watch"] 49 | --- 50 | apiVersion: rbac.authorization.k8s.io/v1 51 | kind: ClusterRoleBinding 52 | metadata: 53 | name: group:oidc:danger-million:restrictedclusteraccess 54 | subjects: 55 | - kind: Group 56 | name: oidc:/danger-million 57 | apiGroup: rbac.authorization.k8s.io 58 | roleRef: 59 | kind: ClusterRole 60 | name: oidc:danger-million:restrictedclusteraccess 61 | apiGroup: rbac.authorization.k8s.io 62 | -------------------------------------------------------------------------------- /kubernetes/projects/steel-ambiguity/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: oidc:steel-ambiguity 5 | namespace: steel-ambiguity 6 | rules: 7 | - apiGroups: ["*"] 8 | resources: ["*"] 9 | verbs: ["*"] 10 | resourceNames: [] 11 | # Exclude ResourceQuotas, ceph.rook.io, and appproject.argoproj.io using separate deny rules (not natively supported in Kubernetes RBAC). 12 | # You must ensure there are no other Roles granting access to these resources. 13 | - apiGroups: [""] 14 | resources: ["resourcequotas"] 15 | verbs: ["list", "get", "watch"] 16 | - apiGroups: ["ceph.rook.io"] 17 | resources: ["*"] 18 | verbs: ["list", "get", "watch"] 19 | - apiGroups: ["appproject.argoproj.io"] 20 | resources: ["*"] 21 | verbs: ["list", "get", "watch"] 22 | --- 23 | apiVersion: rbac.authorization.k8s.io/v1 24 | kind: RoleBinding 25 | metadata: 26 | name: group:oidc:steel-ambiguity 27 | namespace: steel-ambiguity 28 | subjects: 29 | - kind: Group 30 | name: oidc:/steel-ambiguity 31 | apiGroup: rbac.authorization.k8s.io 32 | roleRef: 33 | kind: Role 34 | name: oidc:steel-ambiguity 35 | apiGroup: rbac.authorization.k8s.io 36 | --- 37 | apiVersion: rbac.authorization.k8s.io/v1 38 | kind: ClusterRole 39 | metadata: 40 | name: oidc:steel-ambiguity:restrictedclusteraccess 41 | rules: 42 | - apiGroups: ["storage.k8s.io"] 43 | resources: ["storageclasses"] 44 | verbs: ["list", "get", "watch"] 45 | - apiGroups: [""] 46 | resources: 47 | ["namespaces", "persistentvolumes", "nodes", "persistentvolumeclaims"] 48 | verbs: ["list", "get", "watch"] 49 | --- 50 | apiVersion: rbac.authorization.k8s.io/v1 51 | kind: ClusterRoleBinding 52 | metadata: 53 | name: group:oidc:steel-ambiguity:restrictedclusteraccess 54 | subjects: 55 | - kind: Group 56 | name: oidc:/steel-ambiguity 57 | apiGroup: rbac.authorization.k8s.io 58 | roleRef: 59 | kind: ClusterRole 60 | name: oidc:steel-ambiguity:restrictedclusteraccess 61 | apiGroup: rbac.authorization.k8s.io 62 | -------------------------------------------------------------------------------- /kubernetes/projects/storm-paragraph/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: oidc:storm-paragraph 5 | namespace: storm-paragraph 6 | rules: 7 | - apiGroups: ["*"] 8 | resources: ["*"] 9 | verbs: ["*"] 10 | resourceNames: [] 11 | # Exclude ResourceQuotas, ceph.rook.io, and appproject.argoproj.io using separate deny rules (not natively supported in Kubernetes RBAC). 12 | # You must ensure there are no other Roles granting access to these resources. 13 | - apiGroups: [""] 14 | resources: ["resourcequotas"] 15 | verbs: ["list", "get", "watch"] 16 | - apiGroups: ["ceph.rook.io"] 17 | resources: ["*"] 18 | verbs: ["list", "get", "watch"] 19 | - apiGroups: ["appproject.argoproj.io"] 20 | resources: ["*"] 21 | verbs: ["list", "get", "watch"] 22 | --- 23 | apiVersion: rbac.authorization.k8s.io/v1 24 | kind: RoleBinding 25 | metadata: 26 | name: group:oidc:storm-paragraph 27 | namespace: storm-paragraph 28 | subjects: 29 | - kind: Group 30 | name: oidc:/storm-paragraph 31 | apiGroup: rbac.authorization.k8s.io 32 | roleRef: 33 | kind: Role 34 | name: oidc:storm-paragraph 35 | apiGroup: rbac.authorization.k8s.io 36 | --- 37 | apiVersion: rbac.authorization.k8s.io/v1 38 | kind: ClusterRole 39 | metadata: 40 | name: oidc:storm-paragraph:restrictedclusteraccess 41 | rules: 42 | - apiGroups: ["storage.k8s.io"] 43 | resources: ["storageclasses"] 44 | verbs: ["list", "get", "watch"] 45 | - apiGroups: [""] 46 | resources: 47 | ["namespaces", "persistentvolumes", "nodes", "persistentvolumeclaims"] 48 | verbs: ["list", "get", "watch"] 49 | --- 50 | apiVersion: rbac.authorization.k8s.io/v1 51 | kind: ClusterRoleBinding 52 | metadata: 53 | name: group:oidc:storm-paragraph:restrictedclusteraccess 54 | subjects: 55 | - kind: Group 56 | name: oidc:/storm-paragraph 57 | apiGroup: rbac.authorization.k8s.io 58 | roleRef: 59 | kind: ClusterRole 60 | name: oidc:storm-paragraph:restrictedclusteraccess 61 | apiGroup: rbac.authorization.k8s.io 62 | -------------------------------------------------------------------------------- /kubernetes/core/harbor/certs/harbor-internal-certs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: harbor-core-internal-tls 5 | spec: 6 | secretName: harbor-core-internal-tls 7 | usages: 8 | - digital signature 9 | - key encipherment 10 | - server auth 11 | - client auth 12 | dnsNames: 13 | - harbor-core 14 | - harbor-portal 15 | - 127.0.0.1 16 | issuerRef: 17 | kind: Issuer 18 | name: harbor-internal-ca-issuer 19 | --- 20 | apiVersion: cert-manager.io/v1 21 | kind: Certificate 22 | metadata: 23 | name: harbor-jobservice-internal-tls 24 | spec: 25 | secretName: harbor-jobservice-internal-tls 26 | usages: 27 | - digital signature 28 | - key encipherment 29 | - server auth 30 | - client auth 31 | dnsNames: 32 | - harbor-jobservice 33 | issuerRef: 34 | kind: Issuer 35 | name: harbor-internal-ca-issuer 36 | --- 37 | apiVersion: cert-manager.io/v1 38 | kind: Certificate 39 | metadata: 40 | name: harbor-registry-internal-tls 41 | spec: 42 | secretName: harbor-registry-internal-tls 43 | usages: 44 | - digital signature 45 | - key encipherment 46 | - server auth 47 | - client auth 48 | dnsNames: 49 | - harbor-registry 50 | issuerRef: 51 | kind: Issuer 52 | name: harbor-internal-ca-issuer 53 | --- 54 | apiVersion: cert-manager.io/v1 55 | kind: Certificate 56 | metadata: 57 | name: harbor-portal-internal-tls 58 | spec: 59 | secretName: harbor-portal-internal-tls 60 | usages: 61 | - digital signature 62 | - key encipherment 63 | - server auth 64 | - client auth 65 | dnsNames: 66 | - harbor-portal 67 | issuerRef: 68 | kind: Issuer 69 | name: harbor-internal-ca-issuer 70 | --- 71 | apiVersion: cert-manager.io/v1 72 | kind: Certificate 73 | metadata: 74 | name: harbor-trivy-internal-tls 75 | spec: 76 | secretName: harbor-trivy-internal-tls 77 | usages: 78 | - digital signature 79 | - key encipherment 80 | - server auth 81 | - client auth 82 | dnsNames: 83 | - harbor-trivy 84 | issuerRef: 85 | kind: Issuer 86 | name: harbor-internal-ca-issuer 87 | -------------------------------------------------------------------------------- /kubernetes/core/cert-manager/certbot.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: cert-manager.io/v1 3 | kind: ClusterIssuer 4 | metadata: 5 | name: letsencrypt-dns01 6 | spec: 7 | acme: 8 | server: https://acme-v02.api.letsencrypt.org/directory 9 | email: daniel.a.manners@gmail.com 10 | privateKeySecretRef: 11 | name: letsencrypt-dns01-key 12 | solvers: 13 | - dns01: 14 | webhook: 15 | groupName: capi-core.homelab.danmanners.com 16 | solverName: pdns 17 | config: 18 | host: http://powerdns-api.powerdns.svc.cluster.local 19 | apiKeySecretRef: 20 | name: as-secrets 21 | namespace: powerdns 22 | key: api-key 23 | # This should generally be left unset, and used 24 | # only if you have a proxy in front of the PowerDNS API 25 | # that requires a different value. 26 | serverID: localhost 27 | # TTL for DNS records 28 | ttl: 120 # seconds 29 | # Timeout for requests to the PDNS api server 30 | timeout: 30 # seconds 31 | --- 32 | apiVersion: cert-manager.io/v1 33 | kind: ClusterIssuer 34 | metadata: 35 | name: letsencrypt-dns01-stage 36 | spec: 37 | acme: 38 | server: https://acme-staging-v02.api.letsencrypt.org/directory 39 | email: daniel.a.manners@gmail.com 40 | privateKeySecretRef: 41 | name: letsencrypt-dns01-stage-key 42 | solvers: 43 | - dns01: 44 | webhook: 45 | groupName: capi-core.homelab.danmanners.com 46 | solverName: pdns 47 | config: 48 | host: http://powerdns-api.powerdns.svc.cluster.local 49 | apiKeySecretRef: 50 | name: as-secrets 51 | namespace: powerdns 52 | key: api-key 53 | # This should generally be left unset, and used 54 | # only if you have a proxy in front of the PowerDNS API 55 | # that requires a different value. 56 | serverID: localhost 57 | # TTL for DNS records 58 | ttl: 120 # seconds 59 | # Timeout for requests to the PDNS api server 60 | timeout: 30 # seconds 61 | -------------------------------------------------------------------------------- /taskfile.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | tasks: 4 | install_tools: 5 | desc: Install the required tools 6 | dir: "{{.USER_WORKING_DIR}}" 7 | internal: true 8 | silent: true 9 | preconditions: 10 | - command -v brew 11 | cmds: 12 | - echo "Checking for required tools..." 13 | - | 14 | for tool in trufflehog kubeseal uv yq; do 15 | if ! command -v $tool &> /dev/null; then 16 | brew install $tool 17 | fi 18 | done 19 | - echo "Checking the installed version of Python..." 20 | - | 21 | if [ "$(printf '%s\n' "$(python3 --version | cut -d ' ' -f2)" "$(cat .python-version)" | sort -V | head -n1)" != "$(cat .python-version)" ]; then 22 | echo "Python version is less than $(cat .python-version). Updating Python..."; 23 | brew install python@$(cat .python-version); 24 | else 25 | echo "Python version is up to date."; 26 | fi 27 | - echo "Checking the installed version of pip..." 28 | default: 29 | desc: Initialize the local environment 30 | dir: "{{.USER_WORKING_DIR}}" 31 | preconditions: 32 | - task: install_tools 33 | cmds: 34 | - task: install_tools 35 | - echo "Prepping the uv environment..." 36 | - uv sync 37 | - echo "Configuring the pre-commit hooks..." 38 | - .venv/bin/pre-commit install 39 | kubeseal: 40 | desc: Seal the secrets 41 | summary: | 42 | Usage: 43 | task kubeseal -- 44 | 45 | Example: 46 | task kubeseal -- kubernetes/core/argocd/helo-repo.yaml 47 | dir: "{{.USER_WORKING_DIR}}" 48 | preconditions: 49 | - command -v kubeseal 50 | - if [ -z "./{{.CLI_ARGS}}" ]; then echo "File not specified"; exit 1; fi 51 | cmds: 52 | - echo "Checking if the file exists..." 53 | - if [ ! -f "./{{.CLI_ARGS}}" ]; then echo "File not found"; exit 1; fi 54 | - echo "Checking if the file is already sealed..." 55 | - if grep -q "sealed-secrets.bitnami.com" "./{{.CLI_ARGS}}"; then echo "File is already sealed"; exit 0; fi 56 | - echo "Sealing the secrets..." 57 | - kubeseal --cert keys/sealed-secret.crt -oyaml -{f,w}={{.CLI_ARGS}} 58 | -------------------------------------------------------------------------------- /kubernetes/core/gateway-api/gateway.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: gateway.networking.k8s.io/v1 2 | kind: Gateway 3 | metadata: 4 | name: gwapi 5 | namespace: default 6 | spec: 7 | gatewayClassName: cilium 8 | infrastructure: 9 | annotations: 10 | lbipam.cilium.io/ips: 172.31.0.10 11 | listeners: 12 | - name: http 13 | protocol: HTTP 14 | port: 80 15 | hostname: "*.capi-core.homelab.danmanners.com" 16 | allowedRoutes: 17 | namespaces: 18 | from: All 19 | - name: http-cloud 20 | protocol: HTTP 21 | port: 80 22 | hostname: "*.cloud.danmanners.com" 23 | allowedRoutes: 24 | namespaces: 25 | from: All 26 | - name: https 27 | protocol: HTTPS 28 | port: 443 29 | hostname: "*.capi-core.homelab.danmanners.com" 30 | allowedRoutes: 31 | namespaces: 32 | from: All 33 | tls: 34 | mode: Terminate 35 | certificateRefs: 36 | - name: wildcard 37 | kind: Secret 38 | group: "" 39 | - name: https-cloud 40 | protocol: HTTPS 41 | port: 443 42 | hostname: "*.cloud.danmanners.com" 43 | allowedRoutes: 44 | namespaces: 45 | from: All 46 | tls: 47 | mode: Terminate 48 | certificateRefs: 49 | - name: wildcard 50 | kind: Secret 51 | group: "" 52 | - name: argocd 53 | protocol: TLS 54 | port: 443 55 | hostname: "argocd.cloud.danmanners.com" 56 | allowedRoutes: 57 | namespaces: 58 | from: All 59 | tls: 60 | mode: Passthrough 61 | - name: palworld-server 62 | protocol: UDP 63 | port: 8211 64 | allowedRoutes: 65 | namespaces: 66 | from: Selector 67 | selector: 68 | matchLabels: 69 | app.kubernetes.io/instance: palworld 70 | app.kubernetes.io/name: palworld 71 | - name: palworld-steam 72 | protocol: UDP 73 | port: 27015 74 | allowedRoutes: 75 | namespaces: 76 | from: Selector 77 | selector: 78 | matchLabels: 79 | app.kubernetes.io/instance: palworld 80 | app.kubernetes.io/name: palworld 81 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph-external/readme.md: -------------------------------------------------------------------------------- 1 | # Proxmox Commands 2 | 3 | > [!CAUTION] 4 | > This entire directory is deprecated and will be removed in the future. Please use the new [kubernetes/core/rook-ceph](../rook-ceph) directory instead. 5 | 6 | On the Proxmox host, run the following commands to generate 7 | 8 | ```bash 9 | # Pull the script for Rook-Ceph 1.17 10 | curl -s https://raw.githubusercontent.com/rook/rook/refs/heads/release-1.17/deploy/examples/create-external-cluster-resources.py > create-external-cluster-resources.py 11 | 12 | # Enable the Prometheus module in Ceph 13 | ceph mgr module enable prometheus && sleep 30 14 | 15 | # Run the script to generate the external cluster resource information 16 | python3 create-external-cluster-resources.py \ 17 | --rbd-data-pool-name nvme \ 18 | --cephfs-filesystem-name cephfs \ 19 | --namespace rook-ceph \ 20 | --format bash 21 | 22 | # Make sure to set the permissions for the client.healthchecker user 23 | ceph auth caps client.healthchecker \ 24 | mon 'allow r' osd 'allow r' mgr 'allow r' 25 | ``` 26 | 27 | Now, copy/paste the output into your local terminal. 28 | 29 | Finally, we can install the Rook-Ceph cluster using Helm. 30 | 31 | ```bash 32 | # Install Rook-Ceph using Helm 33 | export clusterNamespace="rook-ceph" 34 | export operatorNamespace="rook-ceph" 35 | export rookcephVersion="v1.17.6" 36 | 37 | helm repo add rook-release https://charts.rook.io/release 38 | helm repo update 39 | 40 | helm upgrade --install --create-namespace \ 41 | --namespace $clusterNamespace rook-ceph --version $rookcephVersion \ 42 | rook-release/rook-ceph -f kubernetes/core/rook-ceph/values.yaml 43 | 44 | helm upgrade --install --create-namespace \ 45 | --namespace $clusterNamespace --version $rookcephVersion \ 46 | rook-ceph-cluster --set operatorNamespace=$operatorNamespace \ 47 | rook-release/rook-ceph-cluster -f kubernetes/core/rook-ceph/cluster.values.yaml 48 | 49 | # Once you import the variables from the python script, we can run this script to import and create the necessary resources: 50 | 51 | curl -s https://raw.githubusercontent.com/rook/rook/refs/heads/release-1.17/deploy/examples/import-external-cluster.sh | bash 52 | 53 | # Finally, add the CephFS Retain StorageClass 54 | kubectl apply -k kubernetes/core/rook-ceph 55 | ``` 56 | -------------------------------------------------------------------------------- /kubernetes/applications/istio.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: istio 6 | namespace: argocd 7 | labels: 8 | chartVersion: &chartVersion 1.26.0 9 | spec: 10 | # Need the ignore differences to prevent ArgoCD from trying to update 11 | # the failurePolicy to Ignore. This is a known issue with Istio and 12 | # ArgoCD. See https://github.com/istio/istio/issues/52785. 13 | ignoreDifferences: 14 | - &istioIgnoreAdmissionWebhooks 15 | group: admissionregistration.k8s.io 16 | kind: ValidatingWebhookConfiguration 17 | name: istiod-default-validator 18 | jsonPointers: 19 | - /webhooks/0/failurePolicy 20 | - <<: *istioIgnoreAdmissionWebhooks 21 | name: istio-validator-istio-system 22 | # Need to ignore the 'divisor' field in the resourceFieldRef for the 23 | # istio-cni-node DaemonSet. This is a known issue with Istio and 24 | # ArgoCD. See https://github.com/istio/istio/issues/53001. 25 | - group: apps 26 | kind: DaemonSet 27 | name: istio-cni-node 28 | jqPathExpressions: 29 | - .spec.template.spec.containers[].env[].valueFrom.resourceFieldRef.divisor 30 | destination: 31 | namespace: istio-system 32 | server: https://kubernetes.default.svc 33 | project: default 34 | sources: 35 | - repoURL: https://github.com/GoodMannersHosting/home-enterprise-labops.git 36 | targetRevision: main 37 | ref: values 38 | - &istioHelm 39 | repoURL: https://istio-release.storage.googleapis.com/charts 40 | name: &ib base 41 | chart: *ib 42 | targetRevision: *chartVersion 43 | helm: 44 | valueFiles: 45 | - $values/kubernetes/core/istio-system/istio-base.values.yaml 46 | - <<: *istioHelm 47 | name: &id istiod 48 | chart: *id 49 | helm: 50 | valueFiles: 51 | - $values/kubernetes/core/istio-system/istiod.values.yaml 52 | - <<: *istioHelm 53 | name: &cni cni 54 | chart: *cni 55 | helm: 56 | valueFiles: 57 | - $values/kubernetes/core/istio-system/cni.values.yaml 58 | - <<: *istioHelm 59 | name: &izt ztunnel 60 | chart: *izt 61 | helm: 62 | valueFiles: 63 | - $values/kubernetes/core/istio-system/ztunnel.values.yaml 64 | syncPolicy: 65 | automated: 66 | prune: true 67 | selfHeal: true 68 | syncOptions: 69 | - ServerSideApply=true 70 | - CreateNamespace=true 71 | -------------------------------------------------------------------------------- /kubernetes/security/policies/vap/hostmount/bindings.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.33.1/validatingadmissionpolicybinding.json 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: ValidatingAdmissionPolicyBinding 5 | metadata: 6 | name: deny-root-hostmount-apps 7 | spec: 8 | policyName: deny-root-hostmount-apps 9 | validationActions: 10 | - Deny 11 | matchResources: 12 | namespaceSelector: 13 | matchLabels: 14 | security: restricted 15 | --- 16 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.33.1/validatingadmissionpolicybinding.json 17 | apiVersion: admissionregistration.k8s.io/v1 18 | kind: ValidatingAdmissionPolicyBinding 19 | metadata: 20 | name: deny-root-hostmount-jobs 21 | spec: 22 | policyName: deny-root-hostmount-jobs 23 | validationActions: 24 | - Deny 25 | matchResources: 26 | namespaceSelector: 27 | matchLabels: 28 | security: restricted 29 | --- 30 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.33.1/validatingadmissionpolicybinding.json 31 | apiVersion: admissionregistration.k8s.io/v1 32 | kind: ValidatingAdmissionPolicyBinding 33 | metadata: 34 | name: deny-root-hostmount-cronjobs 35 | spec: 36 | policyName: deny-root-hostmount-cronjobs 37 | validationActions: 38 | - Deny 39 | matchResources: 40 | namespaceSelector: 41 | matchLabels: 42 | security: restricted 43 | --- 44 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.33.1/validatingadmissionpolicybinding.json 45 | apiVersion: admissionregistration.k8s.io/v1 46 | kind: ValidatingAdmissionPolicyBinding 47 | metadata: 48 | name: deny-root-hostmount-pods 49 | spec: 50 | policyName: deny-root-hostmount-pods 51 | validationActions: 52 | - Deny 53 | matchResources: 54 | namespaceSelector: 55 | matchLabels: 56 | security: restricted 57 | --- 58 | # yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/refs/heads/master/v1.33.1/validatingadmissionpolicybinding.json 59 | apiVersion: admissionregistration.k8s.io/v1 60 | kind: ValidatingAdmissionPolicyBinding 61 | metadata: 62 | name: restrict-namespace-delete 63 | spec: 64 | policyName: restrict-namespace-delete 65 | validationActions: 66 | - Deny 67 | matchResources: 68 | namespaceSelector: 69 | matchLabels: 70 | security: restricted 71 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/db-creds.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: pdns-db-creds 7 | namespace: powerdns 8 | spec: 9 | encryptedData: 10 | POSTGRES_HOST: AgAMsC9KIwBihgH9YfNY/fOOlbfr8nvypG1d+9uDF+BmZtd1W4rwzYtftJdpWbtJCUIq0x/1UOQkCxh3Vm3qYr5rO261bpsFYKwIzCZKbkSlIIs3VbxK1u5PtYfjF7Le+Zp0Ldzo2cHDHcoDlZRUoy7ALMp+a84j5SPufyxWgAd4GfSq+sevohn0/ZeuCkqop5mgLGnwp/itSTUlyHMByX0K48cpvNoiP2FKqJ56T95RoazYT4EBOGKe7tR26YDt3vmWbdyQd/GbfxPSxxS8MRudLT5bZTP3RiONjaVEA4/vu3Q+tTPzRRt5n86ylcJJfDdp/iXblWRlOw7z8x/i8+9QIsk8LyC9QmDK8QlYfGXhcjqhOSUCUkqIcImH+dW0c+p3dnf39uoYHgUXX8Gk9Pq33TVv8uTsYQomq98FoguoGlToWJXfoDZFAZTovaYcPOfn6cp0MJtaJFi4vRfu2c0KBz0fbxYx9h94OrbCAye2sD/K4cVW6j1oQDbzFfuTIFi1JnsDu8XOOaWjtia4Ubmskf8AM8d8ZaHQJm/GIURye6Ni24yMcXdzzl1D/96Q8C7QERreBgyAh2Wl3XACKQQnHA0AeCmpkwpySWUMwp3QUfN/RHmnd/shRGJ9viwLsQzkwb9gYL8CsEYe3P4Cf6dCdmzGuXkLmwYgwH4K7FNntJAF8j32Hw3Xhfi73f9Rw6hqQBEjf0AJ5urgh/i66NPOZaamQKmKU76675kS3JNCdg== 11 | POSTGRES_PASS: AgCHK7P/y+vbV646uhPQDduD0d1pS1Mqx18ewnQZw8J0cRkVg+SkZ4MU8SFCLplZviChrJb5pJXeqAX4h67i6ufHhX0erCjNrbm8ZeViYSnv8DLrBILYb09sjL3onDdt4p66zH+2lowF8Msj/QIvW+p0JmXvZGYGc7oQbvPLpul6Qp7LJLi7l8h3HI77GqnLU7kVNSDJVlIp68nBXggGFTYWDOE+Ai1DGCOK9N1rEFZzWq6slKdJ6goEnpCaBtSYZmv6t7rdUQvdfhoMfB0Wu6l+ucDehOEbm+UVfwop0DZ9UU73X/3jV+/ax+3G7jRzJ7xERD5KC9an9mCXNFJpAlk+fxKahmCJyR29MK7b8lguxiA0BAUhhhva/B1zZVK4Wi276WVxcLxn1lkUY8ZKCML2i7YCC+D57IzH6tsfX2HUJ3BRFKbC59lyaR+VU30NKWc8zI0peIC4pyB/vXmWM0MEqjiVOSJVLaSJB3YKQfHNxwKNmMSo/ACKcS1CUZRxrjdPMe0Jb1VJoVZM532TR38dWdpkIQeJr4G9I1fJZ5oG7o6Xl0okOFucI12hd1c4wB/T/i4OYlLZdXajuxGbHP1ISbPKnZyiTSu2H+oPCOtkcHgTVR7QwsKjBYeGWSU20ICVSqDNe3Hhr1WouYc/RiFWFfAvOyUn+AWnokUNH+OzqTc78lIIWQjmYGyN6TydrdRMO/YxIBtHfRi8QR4E2/8AdCIP6Sjfwlu+SebH0gM+pidb 12 | POSTGRES_USER: AgAqBh4aAE6lczz9R4j0iMhFdqDWi5gjMPfJkim9bLsDm9eJ8dhf8j4AcR27Y7TZcexlOa25+3v9pzhOF3vKh7REd4vIKCj5+afBS6+nJECAG/UyS0/bgm2BBvfKwdVgXndaO786FdwemfWBjKf0kaB6kl1UmeW0gCDcdjr6N36mjcgFh2gQe4nec6U7qmxFhNeVPsE3sgWq/bTrVrDYPCJf5ZoptjRWYFlv1rpEiv0vrAXE49TB/jD4jhXbsPpoUT9z7I8TiYcD79PdvNHWD4QSvpzDtjqsrM6W7LdNgJkgqPQPvE+5YbMrkxoypGvXCdMeXn7mJDi6iKWk1qtwQPaee9ZM8+bHXKtLrp6FZPDcM0rh0TTrL5ozmeXzppvnAVqVkQpAHFhILBy76waEzzTuEiB+GxNEOi/Wpy9+adcDzC3KMiX3/pCFaL8EupE53+cHTJILeLg/tkTKffnkENhdQTBs6Ecs8vLqdfeX4/+9uXJL3VXQdvuM87LTX7EHWv/3NUfbPEaxgmxu10bNGJ/6wlTreyKjo1ry8Zzqd1uy6z2LYWgxjgZuY9fqmjhrDrS+BMXWzihyQy6wi37/KhBD+mKiTcKmrd8LIzAHehNR27jZdihEIc+SCt4GrpmIx2+XXjYSBomXJFDMeoinSrHPEQJa2yz1T8KPhbm54l/QEGpF6TFv6TXNltuL+LkTFwGHxltd 13 | template: 14 | metadata: 15 | creationTimestamp: null 16 | name: pdns-db-creds 17 | namespace: powerdns 18 | type: Opaque 19 | -------------------------------------------------------------------------------- /kubernetes/core/keycloak/db-creds.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: keycloak-db-creds 7 | namespace: keycloak 8 | spec: 9 | encryptedData: 10 | POSTGRES_HOST: AgAfLMPT3xfpnUmlv19Mzw3pEAVP191MEPZm4vRMjG3ulkNO+6guD2rSLLrG8xW4JVo3GLZ+R8XhHHOi3MM+YDKDU/vxhii0NfStDL6vm/YSfTdGBpT3stU9fgpUXCX8VOnAlwLhf/9wKW7x954SF87c8O2EXA+ehfqm5lj1eqA7wT1gtevjWtMfwzqy680Hd5H/iRoBLy/i/KLg0fEbMq4LBUzgllqf2bYexM3q9Fit6Hjn6np2mjuUaLgNd0fJBwKAQIEeTANirKqcxBhha7cKCpqXLjx4vg6eOn1YllNTtPxTme0Q2fvCHxdI0/8VvN5Y0uP6x+zaYCpD6n1QbtezWo2ZjTayWeu8FDXTBo9ozRZawdvEUIxPZlJUHPhoeH4Ui29LGI0Uw6YN04K5Te2dWIVSkLbajReG42/ZQ3H7H7/+inpT/LBzKlc9z0D3Su3S1YiIrCfDrSxXpdDGlNKTdo42DCIqx6jM4Oi/ZlCPDmsDbLqdRMndH6UKBPO58V5p/Q5MmSHZTqICWIPNSKElKIG2U4E3ya4XGjb1uAEs+ohmGIFjQdXd5klW/h9jC2Dmo+p8RwXENvGvt8uDxSVfImrWJhYPTIolpw59Xl3LHZTWtGXhTFAiiyDtjHzTYjzCjycM1F3Ucps/TKwkVSMUu5Md9VnrScVJTfYZ4DdWb0rybsQF8zJH1A+omX+sWUTkh5uXTuzuSCQZFMFvJ/HIJemI9xbzajvLdjCAkAMGKA== 11 | POSTGRES_PASS: AgAIS6mk8k8D4Yzj9omVx6P/QHuOHXaDHD4tC9J2QSiCnoK9vSMjowBTzgl2v5nPxrVyncsMbLdTVC1XXinAOwd4niP0H3i2IEwEbjBGTBGk3GV94S5nJTdN+xcdIo/OhFET+Gw3WzjZvEY8ecE0Scghw+BoVwtL90nNz4tTeUWBVs+NOtdTRrJPUB2JeZIUfMynvr3ProM6URKHAq36qYLyjFoKqTMIsQa0AuwLM7C+RcKV9JqZqE7oycXIF6W8wiyXXvKQr4cc7DUtsQ7jRhQ2PuEAkf0Avfdqc1e8JEU2sL0MbLEO1ip2JfVkYS75b1Ma00EcBPosuoM/xNl65W2Jmo5SJ07RtFe0xQM469YY7SOX0GHgWkRlwJO9wOwiCYLRB6HzRv8Mu638gCUw6I2foWn+aFGULKDl+JDvImAkxKIQE/pR1RXi3oh9wGr08dN7kjHvT33BKROOJY7C+p/qJZqlUYX2C/D21Oiu6le32x/UtxRCqgs5ziKOKNEbKl3FkDAZVkvB0JI+CafcWpxLS8WkMRKUJvqGXknFNQzofjru2Z1L5N303szYxqaZbk6CVUAtUAYpJTY4Ele975dv+URtsrK5I3EMPZU4G9h9iysSaWcXnD0oZgUvLGamYRhxvSNGl6pd7f+bqV4L7Lb7N0aHb4S0K7GUyZ7ALr4sIdnf1rojOn7c/Yu8jr73pWtoOEOv4s0X5ymI6Yhkp8xVXq2XeKfK5Hemx9zEQJG0dwR3gvI= 12 | POSTGRES_USER: AgAyqsu00EjwH+RoTLJV0jENjOpeu3UwaUdlgsHd/yezx57Yn8IxjWoHCGlcyTEuhAbGfluw4UNJy7t9ujxEiktlUnfZmKYhMGSNqsMq76Xtwlc32D196/btXCQa94DNeWcuMTcVPEv5VY6mdCMcxQdZD0wp19shuhGERFl4YSj4mzh93zLd/O0/lB+xlnHJ+00cEC23hDA5dSZTlSKZ9uB1yz8IxV8yiuvWSts0pVegZCT/WQrQ4EAsUU7iloA3DRAsHeJlcwN/iwJO+bxvnlva6k+4Djo/oJa6Wxz72It7Glq/YlmopESeOIXYmLMmx0XxYxIUNMCkC/hwAPWt68qn0hvG1ZfKnnYmpf0I4ml8N/vwqPh+TwG2A2OemoQsfgaloXwcc8Zg0xtEmkogym1MGsLXghmXLDwUfJBeQ2gVWyLbF+2ogTM0ZkG7WOP7J14xtVlEM4JlKmSIsTbb7gNdqDD3HHKWVqdyYy58/QcjnJzvz9SJxTKLcuA3McWRHl3bSU7q/7vc+xYl6K3L585LKAsOF5PptajDzKXCPo5Mot5DqJ/CLtaRnI2KQGHxksVr0Vg+h9dIoN2l/ENy+05FRDLO6j+nyWgwnEkg2BybvjUfO7T6pBJjhKkGSDjQzeX+r0E08/dpLbtxlbPRnnEsHB9CtTILHSBuN71tsTUDXrwQn4f/9y0RvtNd6rYuz67368gWNGZM+g== 13 | template: 14 | metadata: 15 | creationTimestamp: null 16 | name: keycloak-db-creds 17 | namespace: keycloak 18 | type: Opaque 19 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph/readme.md: -------------------------------------------------------------------------------- 1 | # Rook Ceph Installation Guide 2 | 3 | ```bash 4 | # Install Rook-Ceph using Helm 5 | export clusterNamespace="rook-ceph" 6 | export operatorNamespace="rook-ceph" 7 | export rookcephVersion="v1.17.7" 8 | 9 | helm repo add rook-release https://charts.rook.io/release 10 | helm repo update 11 | 12 | helm upgrade --install --create-namespace \ 13 | --namespace $clusterNamespace rook-ceph --version $rookcephVersion \ 14 | rook-release/rook-ceph -f kubernetes/core/rook-ceph/operator.values.yaml 15 | 16 | helm upgrade --install --create-namespace \ 17 | --namespace $clusterNamespace --version $rookcephVersion \ 18 | rook-ceph-cluster --set operatorNamespace=$operatorNamespace \ 19 | rook-release/rook-ceph-cluster -f kubernetes/core/rook-ceph/cluster.values.yaml 20 | 21 | # Finally, add the Retain StorageClass 22 | kubectl apply -k kubernetes/core/rook-ceph 23 | ``` 24 | 25 | ## Re-Installing Rook-Ceph 26 | 27 | If something goes wrong and you need to re-install Rook-Ceph, you can follow these steps: 28 | 29 | 1. Delete the Rook-Ceph Cluster and BlockPool 30 | 2. Patch out the finalizers on the blookpool resource 31 | 3. Wait for everything to be deleted 32 | 4. Open a debug shell on each node and wipe the disks 33 | 34 | ```bash 35 | for node in $(k get nodes -ojsonpath='{.items[*].metadata.name}'); do 36 | kubectl -n kube-system debug node/${node} --image ubuntu --profile sysadmin -it 37 | done 38 | 39 | # For each of the nodes, run the command below 40 | # CRITICAL CRITICAL CRITICAL CRITICAL WARNING: Make sure you know EXACTLY which disks you are nuking! 41 | # This will wipe the disks and remove all data on them. 42 | DISKS="space separated list of disks to nuke" 43 | apt update && apt install -y fdisk gdisk parted -y 44 | for disk in ${DISKS}; do 45 | DISK="/dev/$disk" 46 | sgdisk --zap-all $DISK 47 | dd if=/dev/zero of="$DISK" bs=1K count=200 oflag=direct,dsync seek=0 # Clear at offset 0 48 | dd if=/dev/zero of="$DISK" bs=1K count=200 oflag=direct,dsync seek=$((1 * 1024**2)) # Clear at offset 1GB 49 | dd if=/dev/zero of="$DISK" bs=1K count=200 oflag=direct,dsync seek=$((10 * 1024**2)) # Clear at offset 10GB 50 | dd if=/dev/zero of="$DISK" bs=1K count=200 oflag=direct,dsync seek=$((100 * 1024**2)) # Clear at offset 100GB 51 | dd if=/dev/zero of="$DISK" bs=1K count=200 oflag=direct,dsync seek=$((1000 * 1024**2)) # Clear at offset 1000GB 52 | partprobe $DISK; 53 | done 54 | ``` 55 | 56 | Finally, reboot the nodes. 57 | 58 | ```bash 59 | talosctl --talosconfig=./clusterconfig/talosconfig reboot -n=172.21.0.1{5..8} 60 | ``` 61 | 62 | Then, we can go ahead and re-install Rook-Ceph using the commands provided above. 63 | -------------------------------------------------------------------------------- /kubernetes/core/kube-system/external-dns/values.yaml: -------------------------------------------------------------------------------- 1 | provider: 2 | name: pdns 3 | env: 4 | - name: PDNS_API_KEY 5 | valueFrom: 6 | secretKeyRef: 7 | name: as-secrets 8 | key: api-key 9 | extraArgs: 10 | - --pdns-server=http://powerdns-api.powerdns.svc.cluster.local 11 | # On MacOS, you can generate a server-id with: 12 | # uuidgen | tr '[:upper:]' '[:lower:]' | tr -dc '0-9a-zA-Z' 13 | - --pdns-server-id=localhost 14 | - --pdns-api-key=$(PDNS_API_KEY) 15 | podSecurityContext: 16 | runAsNonRoot: false 17 | SecurityContext: 18 | runAsNonRoot: true 19 | interval: 30s 20 | logFormat: json 21 | logLevel: debug 22 | triggerLoopOnEvent: true 23 | policy: sync 24 | sources: 25 | - service 26 | - gateway-httproute 27 | - gateway-tlsroute 28 | - gateway-tcproute 29 | - gateway-udproute 30 | txtOwnerId: capi-core 31 | txtPrefix: k8s.capi-core. 32 | domainFilters: 33 | - "cloud.danmanners.com" 34 | - "capi-core.homelab.danmanners.com" 35 | - "core.goodmannershosting.com" 36 | initContainers: 37 | - name: wait-for-powerdns 38 | image: docker.io/library/alpine:3.22 39 | env: 40 | - name: EXTERNAL_DNS_DOMAIN_FILTER 41 | value: "cloud.danmanners.com,capi-core.homelab.danmanners.com,core.goodmannershosting.com" 42 | - name: POWERDNS_HTTP_API_URL 43 | value: powerdns-api.powerdns.svc.cluster.local 44 | - name: EXTERNAL_DNS_PDNS_API_KEY 45 | valueFrom: 46 | secretKeyRef: 47 | name: as-secrets 48 | key: api-key 49 | command: 50 | - /bin/ash 51 | args: 52 | - -c 53 | # Script below adapted from this comment: https://github.com/kubernetes-sigs/external-dns/issues/1400#issuecomment-722324037, thanks @andye2004! 54 | - | 55 | # Install Packages 56 | apk add --no-cache curl jq netcat-openbsd 57 | 58 | # Wait for PowerDNS HTTP API to be available 59 | until nc -w1 -vz ${POWERDNS_HTTP_API_URL} 80 2&>1 > /dev/null; do 60 | echo "The endpoint ${POWERDNS_HTTP_API_URL} is not yet responsive, sleeping..." 61 | sleep 3 62 | done 63 | 64 | for zone in $(echo "${EXTERNAL_DNS_DOMAIN_FILTER}" | tr ',' ' '); do 65 | echo "Checking if zone [${zone}] already exists..." 66 | if ! curl -sH "X-API-Key: ${EXTERNAL_DNS_PDNS_API_KEY}" "http://${POWERDNS_HTTP_API_URL}/api/v1/servers/localhost/zones/${zone}." | jq . > /dev/null 2>&1; then 67 | echo "Creating zone for ${zone}..." 68 | curl -s -d '{ 69 | "name": "'${zone}'.", 70 | "kind": "Native", 71 | "masters": [], 72 | "nameservers": [ "'${zone}'." ] }' \ 73 | -H "X-API-Key: ${EXTERNAL_DNS_PDNS_API_KEY}" \ 74 | "http://${POWERDNS_HTTP_API_URL}/api/v1/servers/localhost/zones" | jq . 75 | else 76 | echo "Zone already exists for ${zone}..." 77 | fi 78 | done 79 | -------------------------------------------------------------------------------- /kubernetes/services/github-action-runners/runners/values.yaml: -------------------------------------------------------------------------------- 1 | githubConfigUrl: "https://github.com/goodmannershosting" 2 | githubConfigSecret: gh-app-goodmannershosting 3 | minRunners: 1 4 | maxRunners: 6 5 | runnerGroup: "default" 6 | runnerScaleSetName: "shr" 7 | containerMode: 8 | type: "dind" 9 | 10 | listenerTemplate: 11 | spec: 12 | containers: 13 | - name: listener 14 | securityContext: 15 | runAsUser: 1000 16 | 17 | controllerServiceAccount: 18 | namespace: github 19 | name: arc 20 | 21 | template: 22 | template: 23 | spec: 24 | initContainers: 25 | - name: init-dind-externals 26 | image: ghcr.io/actions/actions-runner:latest 27 | command: [ "cp", "-r", "/home/runner/externals/.", "/home/runner/tmpDir/" ] 28 | volumeMounts: 29 | - name: dind-externals 30 | mountPath: /home/runner/tmpDir 31 | - name: dind 32 | image: docker:dind 33 | args: 34 | - dockerd 35 | - --host=unix:///var/run/docker.sock 36 | - --group=$(DOCKER_GROUP_GID) 37 | env: 38 | - name: DOCKER_GROUP_GID 39 | value: "123" 40 | securityContext: 41 | privileged: true 42 | restartPolicy: Always 43 | startupProbe: 44 | exec: 45 | command: 46 | - docker 47 | - info 48 | initialDelaySeconds: 0 49 | failureThreshold: 24 50 | periodSeconds: 5 51 | volumeMounts: 52 | - name: work 53 | mountPath: /home/runner/_work 54 | - name: dind-sock 55 | mountPath: /var/run 56 | - name: dind-externals 57 | mountPath: /home/runner/externals 58 | containers: 59 | - name: runner 60 | image: ghcr.io/actions/actions-runner:latest 61 | command: [ "/home/runner/run.sh" ] 62 | env: 63 | - name: DOCKER_HOST 64 | value: unix:///var/run/docker.sock 65 | - name: RUNNER_WAIT_FOR_DOCKER_IN_SECONDS 66 | value: "120" 67 | volumeMounts: 68 | - name: work 69 | mountPath: /home/runner/_work 70 | - name: dind-sock 71 | mountPath: /var/run 72 | volumes: 73 | - name: work 74 | ephemeral: 75 | volumeClaimTemplate: 76 | spec: 77 | accessModes: [ "ReadWriteOnce" ] 78 | storageClassName: "ceph-rbd" 79 | resources: 80 | requests: 81 | storage: 10Gi 82 | - name: dind-sock 83 | emptyDir: {} 84 | - name: dind-externals 85 | ephemeral: 86 | volumeClaimTemplate: 87 | spec: 88 | accessModes: [ "ReadWriteOnce" ] 89 | storageClassName: "ceph-rbd" 90 | resources: 91 | requests: 92 | storage: 10Gi 93 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/as-secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: as-secrets 7 | namespace: powerdns 8 | spec: 9 | encryptedData: 10 | api-key: AgA3aT6KtRU8RTHTHi716fZ4MBpK3yphE4YBopNRoQML3o3XQi0jBPEBAoz69ikxy+F7kAmgzhm/LMw2CPTQAD7rvh/ZSS2loDElf6jAkSXTo1GsSRLpmI71CG/PeYgv3dL3kugxNqE3WzRMH8aX6LqDzoN3miNRd66pCra6pWJCT6i7LCm2bOt1ZGabtj9iFb2zpBTZV3vUAgOddtAymUMHCFMbD4vYu3PCxmYMuTYS3+mQxEb21j9c3Alr/Mdn7vljD9DmNCI3RYQHPPsAKoDsiJUDHbiVzSlXaGewyr/oOd4ovwNmyT0p/lsgZBZq9Ozm5Fc7fmqEy33pJ4SGs1hYsz//tf5Q0nwL0YPc+w793VpWDdrC/2l+ulTkTCJEP+P8ZgP3j3xCH1iVCE0tE/eoHUdo9EWKWkiOGnGgZY/UTpDhws5rEAVulzY+sFTgYhzTqjzd1EKO5A7DjKs0wlSDB6ZR+qXDiCDqffnye6itsahZhqgAux7OLhG/D7I5afxhEI5HBidCBwcqa6S+v9IKbImb2dQLYj26Su2sjCLNcTMMbxWALo6biKZGyLxnUCEKhJDXy/B0Oja5+BAwE8WLxxAWBSzmCqEbkKlW6Nh0TyOGcwoX8gOFqcCVsW8tLsXjryREngVEqNuGFXm6Kts3eR+m68IWwFT2JWVy4lVdKYAIeqVnNGNfYZjz88HTtJ3IIWTHk49qfREXOEKRCVvWT+OPd8CNdpv19I0dvjgRIL7iQ5uXDfyvoHk5Mo7SJMk= 11 | ci-job-id: AgCJwhE0iMuY3oZn4VWHT2vOtMj1e5MRS13dtMjhBGsLE5HS/J35hom6L10P9UPdJMoNNmzIfob/6w4hcECzTPiOQOIiCFd0pQueIANV80hHWCmQsrUOJ6NqEaeblnw8EJdQY0rVqBzSthBY0XsyHH1lvIqA2g7os3djADFPzxTsp0HTBrCDyny9BWGVy5hXwBTY72peHF9ZVEnhvQjKg9oF+VdVctLqMt7Yt6TpY1qN7qQsJxSEniDd/Yt0PY+mqzqCljejebtTnSKuYrTukTCOv4wqnh2vzAB0r/WvcaHb/LJIEQHs1Uo+ohQsqtKn4DwxlzsVpDOaur7CJo4+v8pJ8ZwWNv5bhspWc7Dm4xAPVHSrnvb13dCW/ipCPHOk89eE7kUHwnJZKh5gF6SIbDQcS2pMkSnz+He/LnupiIp5ewOZW04BaN0gs0jDoAbm5ovSkWzZcDcNjvbTNyGhz3s1j8i0pq1a49SIxYYwgli6NUhTptJhO9kO2IGuZPpc+h/WOAVlrMm7D/ZLfOiKxa6/N2c/EhCr+5ZPELOzKAQJGx47BgMOcPhQzvMStEiDHgvoTdVPak3HjIl0ugrIiTBMtKgTqBRQ9/a1TpYPnKD71U2Fb4Iue6PzgjdOkgszc+lemCcheSlEI5JZMV5bjvGMG0FY6falf8y6SimmuMthW27Y3IzMP19KLZ7S02hHooJrFOPbjd8dxj/b1XSxTlQRGE+IsrvpStCPCqVMJLc4bg== 12 | key: AgBJXFLFirW39dR3heDhhQindXCOwtmoxfuuYEK2a4k/rYVP7MiR07AVffTl8vh7ua8PwzyqldV8YHC16PB48ijCg7+EFtiIfp0PVdBO6EVOtfc1nDeVhZshMnRNmCdkzrlmCvPdD9MXV34M/ryYVFbv0C7MegGlNhK9KNGleon6J1o0T8PKpqzEnMOcmULgP4/GZZ1112XShyCmm8Yyrb4HCnydJRhj/5e35tH/H7YYUi/g6yEGP8CSQ+OQ4Vw5bL59/TSlRjAMiMdlA05d07r5I0ZK3Ewbb8zmgCIQ5mVT/FKZ6OkLw3yStZXrx2JkoSzcKrau6u0h4UlT1vi/z3hKEGbfXhhvjGwgEhOR4LayGg2BMnyx5UUR/Kxlr8HyY4F+XfnTHFSFNh1E3i0AS6PCi5aSuVbTqqXC8I2cPLcyZ2EXK8ggxXi+ntUWiLauS90jwQpzF1qJ/PeiqTBXJt+Yvt4zZUX8CylblCOamZ6oTiP2fqP37WsJdkktwVAUQT06yI8ungsMxKh7hvGxD4pkQvEtbZGkrMqpa5QTfyA3hLY/Zflh0Dki4TwfRouDE77BrMVDQ5gbWyLPLslcJ2w4gJDeKeAiecuy/YqeQ4LUgPLVSZh2i4ray8/ONboOQqvJXl2Z+lFe8v3O6Luku4zZx2SJAIuy6f3jtlDWTFT5boTxdsfHzpM91BBmMxFcvgIw2cU3dypnjOk6PP5KP08enBFRmK7aGzitVc8HRQrmn5Mj4wJVUUItbjDQ1QiJToO2AlQXuOXqa1Daq8SL19Qm225PtRGhmzMFpwoH4x95h9pxgYbSfkH5zXaOroUu9z1E3u7CTftfMprEF436XzMytCYAnQWHDuDPhdbSqL2s0A== 13 | template: 14 | metadata: 15 | annotations: 16 | reflector.v1.k8s.emberstack.com/reflection-allowed: "true" 17 | reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: kube-system,cert-manager,external-dns 18 | reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true" 19 | creationTimestamp: null 20 | name: as-secrets 21 | namespace: powerdns 22 | type: Opaque 23 | -------------------------------------------------------------------------------- /kubernetes/core/rook-ceph-external/values.yaml: -------------------------------------------------------------------------------- 1 | operatorNamespace: rook-ceph 2 | clusterName: capi-core 3 | toolbox: 4 | enabled: true # true 5 | image: quay.io/ceph/ceph:v19.2.1 6 | containerSecurityContext: 7 | runAsNonRoot: true 8 | runAsUser: 2016 9 | runAsGroup: 2016 10 | capabilities: 11 | drop: [ "ALL" ] 12 | # -- Toolbox resources 13 | resources: 14 | limits: 15 | memory: "1Gi" 16 | requests: 17 | cpu: "100m" 18 | memory: "128Mi" 19 | 20 | monitoring: 21 | enabled: false 22 | 23 | cephClusterSpec: 24 | cephVersion: 25 | image: quay.io/ceph/ceph:v19.2.1 26 | allowUnsupported: false 27 | dataDirHostPath: /var/lib/rook 28 | skipUpgradeChecks: false 29 | continueUpgradeAfterChecksEvenIfNotHealthy: false 30 | waitTimeoutForHealthyOSDInMinutes: 10 31 | upgradeOSDRequiresHealthyPGs: false 32 | mon: 33 | count: 3 34 | allowMultiplePerNode: false 35 | 36 | mgr: 37 | count: 2 38 | allowMultiplePerNode: false 39 | modules: 40 | dashboard: 41 | enabled: true 42 | ssl: true 43 | network: 44 | provider: host 45 | ipFamily: "IPv4" 46 | connections: 47 | encryption: 48 | enabled: false 49 | compression: 50 | enabled: false 51 | requireMsgr2: false 52 | 53 | crashCollector: 54 | disable: false 55 | 56 | logCollector: 57 | enabled: true 58 | periodicity: daily # one of: hourly, daily, weekly, monthly 59 | maxLogSize: 500M # SUFFIX may be 'M' or 'G'. Must be at least 1M. 60 | 61 | cleanupPolicy: 62 | confirmation: "" 63 | sanitizeDisks: 64 | method: quick 65 | dataSource: zero 66 | iteration: 1 67 | allowUninstallWithVolumes: false 68 | 69 | # The option to automatically remove OSDs that are out and are safe to destroy. 70 | removeOSDsIfOutAndSafeToRemove: false 71 | 72 | # priority classes to apply to ceph resources 73 | priorityClassNames: 74 | mon: system-node-critical 75 | osd: system-node-critical 76 | mgr: system-cluster-critical 77 | 78 | storage: 79 | useAllNodes: true 80 | useAllDevices: true 81 | 82 | ingress: 83 | dashboard: {} 84 | # labels: 85 | # external-dns/private: "true" 86 | # annotations: 87 | # external-dns.alpha.kubernetes.io/hostname: dashboard.example.com 88 | # nginx.ingress.kubernetes.io/rewrite-target: /ceph-dashboard/$2 89 | # If the dashboard has ssl: true the following will make sure the NGINX Ingress controller can expose the dashboard correctly 90 | # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 91 | # nginx.ingress.kubernetes.io/server-snippet: | 92 | # proxy_ssl_verify off; 93 | # host: 94 | # name: dashboard.example.com 95 | # path: "/ceph-dashboard(/|$)(.*)" 96 | # pathType: Prefix 97 | # tls: 98 | # - hosts: 99 | # - dashboard.example.com 100 | # secretName: testsecret-tls 101 | ## Note: Only one of ingress class annotation or the `ingressClassName:` can be used at a time 102 | ## to set the ingress class 103 | # ingressClassName: nginx 104 | 105 | cephBlockPools: {} 106 | cephFileSystems: {} 107 | 108 | cephFileSystemVolumeSnapshotClass: 109 | enabled: false 110 | 111 | cephBlockPoolsVolumeSnapshotClass: 112 | enabled: false 113 | # -- A list of CephObjectStore configurations to deploy 114 | # @default -- See [below](#ceph-object-stores) 115 | cephObjectStores: {} 116 | -------------------------------------------------------------------------------- /kubernetes/core/powerdns/readme.md: -------------------------------------------------------------------------------- 1 | # PowerDNS 2 | 3 | Much of this code has been adopted from [owndomainname/powerdns-stack-over-k8s](https://github.com/owndomainhome/powerdns-stack-over-k8s/tree/main) - give them a star! 4 | 5 | ## Generating a 128-character secret key 6 | 7 | Both options below will generate a 128-character secret key. 8 | 9 | ```bash 10 | # MacOS - openssl 11 | openssl rand -base64 96 | tr -d '\n' 12 | 13 | # MacOS - /dev/urandom 14 | cat /dev/urandom | base64 | tr -dc '0-9a-zA-Z' | head -c128 15 | ``` 16 | 17 | ## Upstream Router Domain Forwarding 18 | 19 | ![image](unifi-dns-settings.png) 20 | 21 | Configure your router to forward your specified domains to the BGP IP of your PowerDNS server. 22 | 23 | ## Enabling Cert-Manager DNS-01 Auth with PowerDNS 24 | 25 | If you want to use Cert-Manager to generate valid Let's Encrypt certificates, you need to make sure that your PowerDNS server is reachable from the internet. If you're using a Unifi Router, you can create a Port Forwarding rule to forward the DNS requests to your PowerDNS server. In **Settings > Routing > Port Forwarding**, create a new entry: 26 | 27 | ![image](unifi-dns-nat.png) 28 | 29 | - WAN Port: 53 30 | - Forwarding IP Address: `` 31 | - Forwarding Port: 53 32 | - Protocol: UDP 33 | 34 | ## Deploying PowerDNS 35 | 36 | ```bash 37 | kubectl apply -k kubernetes/core/powerdns 38 | 39 | helm upgrade --install powerdns bjw-s/app-template \ 40 | --version 4.1.2 --namespace powerdns \ 41 | -f kubernetes/core/powerdns/values.yaml 42 | ``` 43 | 44 | ## Port Forwarding 45 | 46 | To securely access the PowerDNS API, you can use port forwarding: 47 | 48 | ```bash 49 | kubectl port-forward -n powerdns svc/powerdns-api 8080:80 50 | ``` 51 | 52 | ## Creating a new zone 53 | 54 | ```bash 55 | curl -X POST \ 56 | --data '{ 57 | "name": "cloud.danmanners.com.", 58 | "kind": "Master", 59 | "dnssec": false, 60 | "soa-edit": "INCEPTION-INCREMENT", 61 | "masters": [], 62 | "nameservers": [ 63 | "172.31.0.15." 64 | ] 65 | }' \ 66 | -vH "X-API-Key: $(kubectl get secrets -n powerdns as-secrets -ojson | jq -r '.data."api-key"|@base64d')" \ 67 | http://localhost:8000/api/v1/servers/localhost/zones 68 | ``` 69 | 70 | ## Deleting TXT Records 71 | 72 | ```bash 73 | for RECORD in \ 74 | argocd; do 75 | curl -X PATCH --data '{ 76 | "rrsets": [ 77 | { 78 | "changetype": "DELETE", 79 | "type": "CNAME", 80 | "name": "'${RECORD}'.cloud.danmanners.com." 81 | } 82 | ] 83 | }' -H "X-API-Key: $(kubectl get secrets -n powerdns as-secrets -ojson | jq -r '.data."api-key"|@base64d')" \ 84 | "http://localhost:8000/api/v1/servers/localhost/zones/cloud.danmanners.com" 85 | echo "Deleted ${RECORD}.cloud.danmanners.com" 86 | done 87 | ``` 88 | 89 | ## Deleting A Records 90 | 91 | ```bash 92 | for RECORD in \ 93 | ollama \ 94 | keycloak; do 95 | curl -X PATCH --data '{ 96 | "rrsets": [ 97 | { 98 | "changetype": "DELETE", 99 | "type": "A", 100 | "name": "'${RECORD}'.cloud.danmanners.com." 101 | } 102 | ] 103 | }' -H "X-API-Key: $(kubectl get secrets -n powerdns as-secrets -ojson | jq -r '.data."api-key"|@base64d')" \ 104 | "http://localhost:8000/api/v1/servers/localhost/zones/cloud.danmanners.com" 105 | echo "Deleted ${RECORD}.cloud.danmanners.com" 106 | done 107 | ``` 108 | -------------------------------------------------------------------------------- /kubernetes/services/n8n/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | defaultPodOptions: 3 | automountServiceAccountToken: true 4 | enableServiceLinks: true 5 | restartPolicy: Always 6 | securityContext: 7 | fsGroup: 1000 8 | fsGroupChangePolicy: OnRootMismatch 9 | 10 | controllers: 11 | main: 12 | enabled: true 13 | type: deployment 14 | replicas: 1 15 | revisionHistoryLimit: 2 16 | containers: 17 | core: 18 | ports: 19 | - name: http 20 | containerPort: &port 5678 21 | protocol: TCP 22 | image: 23 | repository: ghcr.io/n8n-io/n8n 24 | tag: "stable" 25 | pullPolicy: "IfNotPresent" 26 | securityContext: 27 | allowPrivilegeEscalation: true 28 | env: 29 | - name: N8N_HOST 30 | value: n8n.cloud.danmanners.com 31 | - name: N8N_PORT 32 | value: *port 33 | - name: N8N_PROTOCOL 34 | value: http 35 | - name: NODE_ENV 36 | value: production 37 | - name: N8N_TRUST_PROXY 38 | value: true 39 | - name: N8N_SECURE_COOKIE 40 | value: false 41 | - name: WEBHOOK_URL 42 | value: https://n8n.cloud.danmanners.com 43 | - name: GENERIC_TIMEZONE 44 | value: America/New_York 45 | - name: N8N_RUNNERS_ENABLED 46 | value: true 47 | - name: N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS 48 | value: false 49 | - name: NODE_FUNCTION_ALLOW_BUILTIN 50 | value: "*" 51 | - name: NODE_FUNCTION_ALLOW_EXTERNAL 52 | value: dgram 53 | resources: 54 | limits: 55 | cpu: 2 56 | memory: 4Gi 57 | requests: 58 | cpu: 500m 59 | memory: 2Gi 60 | lifecycle: {} 61 | terminationMessagePath: /dev/termination-log 62 | terminationMessagePolicy: File 63 | 64 | service: 65 | core: 66 | enabled: true 67 | controller: main 68 | primary: true 69 | type: ClusterIP 70 | ports: 71 | api: 72 | enabled: true 73 | port: *port 74 | targetPort: http 75 | protocol: TCP 76 | extname: 77 | enabled: true 78 | primary: false 79 | controller: main 80 | type: ExternalName 81 | externalName: unifi-home.homelab.danmanners.com 82 | annotations: 83 | external-dns.alpha.kubernetes.io/hostname: n8n.cloud.danmanners.com 84 | external-dns.alpha.kubernetes.io/ttl: "300" 85 | 86 | route: 87 | core: 88 | enabled: true 89 | kind: HTTPRoute 90 | annotations: 91 | external-dns.alpha.kubernetes.io/controller: "false" 92 | gatus.home-operations.com/enabled: "false" 93 | parentRefs: 94 | - group: gateway.networking.k8s.io 95 | kind: Gateway 96 | name: gwapi 97 | namespace: default 98 | sectionName: https-cloud 99 | hostnames: 100 | - n8n.cloud.danmanners.com 101 | rules: 102 | - backendRefs: 103 | - name: n8n-core 104 | port: *port 105 | weight: 1 106 | matches: 107 | - path: 108 | type: PathPrefix 109 | value: / 110 | timeouts: 111 | backendRequest: 0s 112 | request: 0s 113 | 114 | persistence: 115 | home: 116 | enabled: true 117 | type: persistentVolumeClaim 118 | storageClass: ceph-block-retain 119 | accessMode: ReadWriteOnce 120 | size: 60Gi 121 | retain: true 122 | globalMounts: 123 | - path: /home/node/.n8n 124 | readOnly: false 125 | files: 126 | enabled: true 127 | type: persistentVolumeClaim 128 | storageClass: ceph-block-retain 129 | accessMode: ReadWriteOnce 130 | size: 60Gi 131 | retain: true 132 | globalMounts: 133 | - path: /files 134 | readOnly: false 135 | -------------------------------------------------------------------------------- /kubernetes/core/argocd/values.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | domain: &url argocd.cloud.danmanners.com 3 | hostAliases: 4 | - ip: "172.31.0.10" 5 | hostnames: 6 | - "harbor.cloud.danmanners.com" 7 | - "ollama.cloud.danmanners.com" 8 | - "n8n.cloud.danmanners.com" 9 | - "keycloak.cloud.danmanners.com" 10 | 11 | crds: 12 | install: false 13 | 14 | redis-ha: 15 | enabled: true 16 | 17 | controller: 18 | replicas: 1 19 | 20 | applicationSet: 21 | replicas: 2 22 | 23 | configs: 24 | cm: 25 | admin.enabled: true 26 | url: &fullUrl https://argocd.cloud.danmanners.com 27 | oidc.config: | 28 | name: Keycloak 29 | issuer: https://keycloak.cloud.danmanners.com/realms/gmh 30 | clientID: argocd 31 | clientSecret: $argocd-oidc-secret:oidc.keycloak.clientSecret 32 | requestedScopes: ["openid", "profile", "email", "groups"] 33 | userNameKey: email 34 | overrideClaimMapping: true 35 | rbac: 36 | policy.default: role:readonly 37 | policy.csv: | 38 | p, role:org-admin, applications, create, */*, allow 39 | p, role:org-admin, applications, update, */*, allow 40 | p, role:org-admin, applications, delete, */*, allow 41 | p, role:org-admin, applications, sync, */*, allow 42 | p, role:org-admin, applications, override, */*, allow 43 | p, role:org-admin, applications, action/*, */*, allow 44 | p, role:org-admin, applicationsets, get, */*, allow 45 | p, role:org-admin, applicationsets, create, */*, allow 46 | p, role:org-admin, applicationsets, update, */*, allow 47 | p, role:org-admin, applicationsets, delete, */*, allow 48 | p, role:org-admin, certificates, create, *, allow 49 | p, role:org-admin, certificates, update, *, allow 50 | p, role:org-admin, certificates, delete, *, allow 51 | p, role:org-admin, clusters, create, *, allow 52 | p, role:org-admin, clusters, update, *, allow 53 | p, role:org-admin, clusters, delete, *, allow 54 | p, role:org-admin, repositories, create, *, allow 55 | p, role:org-admin, repositories, update, *, allow 56 | p, role:org-admin, repositories, delete, *, allow 57 | p, role:org-admin, projects, create, *, allow 58 | p, role:org-admin, projects, update, *, allow 59 | p, role:org-admin, projects, delete, *, allow 60 | p, role:org-admin, accounts, update, *, allow 61 | p, role:org-admin, gpgkeys, create, *, allow 62 | p, role:org-admin, gpgkeys, delete, *, allow 63 | p, role:org-admin, exec, create, */*, allow 64 | g, ArgoCDAdmins, role:org-admin 65 | 66 | repoServer: 67 | replicas: 2 68 | # Node Selector to ensure the repo server runs on only AMD64 nodes 69 | nodeSelector: 70 | kubernetes.io/arch: amd64 71 | 72 | server: 73 | replicas: 2 74 | service: 75 | annotations: 76 | gatus.home-operations.com/enabled: "true" 77 | gatus.home-operations.com/endpoint: |- 78 | name: ArgoCD 79 | client: 80 | insecure: true 81 | conditions: 82 | - "[STATUS] == 200" 83 | url: https://argocd-server.argocd.svc.cluster.local/ 84 | method: HEAD 85 | config: 86 | application.instanceLabelKey: argocd.argoproj.io/instance 87 | url: *fullUrl 88 | # Why in the HECK is this here? See below! 89 | # https://argo-cd.readthedocs.io/en/stable/faq/#why-is-my-application-still-outofsync-immediately-after-a-successful-sync 90 | # https://github.com/argoproj/argo-cd/blob/v3.0.0/docs/operator-manual/argocd-cm.yaml#L278 91 | # Thanks a ton to @onedr0p, @toboshii, and @xUnholy for the help in figuring this out! 92 | certificate: 93 | enabled: true 94 | secretName: argocd-tls-cert 95 | duration: 1128h # 47 days 96 | renewBefore: 168h # 7 days 97 | commonName: *url 98 | dnsNames: 99 | - *url 100 | issuer: 101 | kind: ClusterIssuer 102 | name: letsencrypt-dns01 103 | group: cert-manager.io 104 | ingress: 105 | enabled: false 106 | -------------------------------------------------------------------------------- /kubernetes/services/github-action-runners/runners/runner.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Source: gha-runner-scale-set/templates/autoscalingrunnerset.yaml 3 | apiVersion: actions.github.com/v1alpha1 4 | kind: AutoscalingRunnerSet 5 | metadata: 6 | name: shr 7 | namespace: github 8 | labels: 9 | app.kubernetes.io/version: "0.12.1" 10 | actions.github.com/scale-set-name: shr 11 | actions.github.com/scale-set-namespace: github 12 | app.kubernetes.io/component: "autoscaling-runner-set" 13 | annotations: 14 | actions.github.com/values-hash: 1319406b35e3b13fe35f9169db4bed59945400809fcce4de085b7570ab8dca9 15 | actions.github.com/cleanup-manager-role-binding: shr-gha-rs-manager 16 | actions.github.com/cleanup-manager-role-name: shr-gha-rs-manager 17 | actions.github.com/cleanup-no-permission-service-account-name: shr-gha-rs-no-permission 18 | spec: 19 | githubConfigUrl: https://github.com/goodmannershosting 20 | githubConfigSecret: gh-app-goodmannershosting 21 | runnerGroup: nvidia 22 | runnerScaleSetName: shr 23 | maxRunners: 6 24 | minRunners: 1 25 | template: 26 | spec: 27 | dnsPolicy: ClusterFirstWithHostNet 28 | hostAliases: 29 | - ip: "172.31.0.10" 30 | hostnames: 31 | - "harbor.cloud.danmanners.com" 32 | - "ollama.cloud.danmanners.com" 33 | - "n8n.cloud.danmanners.com" 34 | restartPolicy: Never 35 | serviceAccountName: shr-gha-rs-no-permission 36 | securityContext: 37 | fsGroup: 123 38 | initContainers: 39 | - name: init-dind-externals 40 | image: ghcr.io/actions/actions-runner:latest 41 | command: ["cp"] 42 | args: ["-r", "-v", "/home/runner/externals/.", "/home/runner/tmpDir/"] 43 | volumeMounts: 44 | - name: dind-externals 45 | mountPath: /home/runner/tmpDir 46 | securityContext: 47 | allowPrivilegeEscalation: false 48 | runAsUser: 1001 49 | runAsGroup: 123 50 | capabilities: 51 | drop: 52 | - ALL 53 | - name: dind 54 | image: docker:dind 55 | args: 56 | - dockerd 57 | - --host=unix:///var/run/docker.sock 58 | - --group=$(DOCKER_GROUP_GID) 59 | env: 60 | - name: DOCKER_GROUP_GID 61 | value: "123" 62 | securityContext: 63 | privileged: true 64 | restartPolicy: Always 65 | startupProbe: 66 | exec: 67 | command: 68 | - docker 69 | - info 70 | initialDelaySeconds: 0 71 | failureThreshold: 24 72 | periodSeconds: 5 73 | volumeMounts: 74 | - name: work 75 | mountPath: /home/runner/_work 76 | - name: dind-sock 77 | mountPath: /var/run 78 | - name: dind-externals 79 | mountPath: /home/runner/externals 80 | containers: 81 | - name: runner 82 | command: 83 | - /home/runner/run.sh 84 | image: ghcr.io/actions/actions-runner:latest 85 | env: 86 | - name: DOCKER_HOST 87 | value: unix:///var/run/docker.sock 88 | - name: RUNNER_WAIT_FOR_DOCKER_IN_SECONDS 89 | value: "120" 90 | volumeMounts: 91 | - name: work 92 | mountPath: /home/runner/_work 93 | - name: dind-sock 94 | mountPath: /var/run 95 | volumes: 96 | - name: dind-sock 97 | emptyDir: {} 98 | - name: dind-externals 99 | ephemeral: 100 | volumeClaimTemplate: 101 | spec: 102 | accessModes: ["ReadWriteOnce"] 103 | storageClassName: "ceph-block" 104 | resources: 105 | requests: 106 | storage: 20Gi 107 | - name: work 108 | ephemeral: 109 | volumeClaimTemplate: 110 | spec: 111 | accessModes: ["ReadWriteOnce"] 112 | storageClassName: "ceph-block" 113 | resources: 114 | requests: 115 | storage: 12Gi 116 | -------------------------------------------------------------------------------- /.github/workflows/kwok-validation.yaml: -------------------------------------------------------------------------------- 1 | name: KWOK Validation 2 | 3 | on: 4 | push: 5 | branches: [main, develop] 6 | paths: 7 | - "kubernetes/**" 8 | - ".github/workflows/kwok-validation.yaml" 9 | pull_request: 10 | branches: [main, develop] 11 | paths: 12 | - "kubernetes/**" 13 | - ".github/workflows/kwok-validation.yaml" 14 | workflow_dispatch: 15 | 16 | env: 17 | KWOK_KUBE_VERSION: v1.33.0 18 | KUBECTL_VERSION: v1.33.0 19 | HELM_VERSION: v3.19.0 20 | KUSTOMIZE_VERSION: v5.7.1 21 | YQ_VERSION: v4.47.2 22 | BIN_PATH: /usr/local/bin 23 | 24 | jobs: 25 | kwok-validation: 26 | runs-on: 27 | group: nvidia 28 | steps: 29 | - name: Checkout repository 30 | uses: actions/checkout@v5 31 | 32 | - name: Install Golang 33 | uses: actions/setup-go@v6.0.0 34 | with: 35 | go-version: "1.25" 36 | 37 | - name: Install required tooling 38 | run: | 39 | sudo apt-get update 40 | sudo apt-get install -y wget curl jq 41 | 42 | - name: Set up kwok 43 | uses: kubernetes-sigs/kwok@v0.7.0 44 | with: 45 | command: kwok 46 | 47 | - name: Set up kwokctl 48 | uses: kubernetes-sigs/kwok@v0.7.0 49 | with: 50 | command: kwokctl 51 | 52 | - name: Install kubectl 53 | run: | 54 | curl -LO "https://dl.k8s.io/release/${{ env.KUBECTL_VERSION }}/bin/linux/amd64/kubectl" 55 | chmod +x kubectl 56 | sudo mv kubectl ${{ env.BIN_PATH }}/kubectl 57 | kubectl version --client 58 | 59 | - name: Create KWOK cluster 60 | run: | 61 | kwokctl create cluster \ 62 | --quiet-pull --runtime binary 63 | kwokctl scale node --replicas 3 64 | env: 65 | KWOK_KUBE_VERSION: ${{ env.KWOK_KUBE_VERSION }} 66 | 67 | - name: Install YQ 68 | run: | 69 | wget https://github.com/mikefarah/yq/releases/download/${{ env.YQ_VERSION }}/yq_linux_amd64.tar.gz -O - | tar xz 70 | sudo mv yq_linux_amd64 ${{ env.BIN_PATH }}/yq 71 | 72 | - name: Install Helm 73 | run: | 74 | curl -fsSL https://get.helm.sh/helm-${{ env.HELM_VERSION }}-linux-amd64.tar.gz -o helm.tar.gz 75 | tar -zxvf helm.tar.gz 76 | sudo mv linux-amd64/helm ${{ env.BIN_PATH }}/helm 77 | rm -rf linux-amd64 helm.tar.gz 78 | helm version 79 | 80 | - name: Install Kustomize 81 | run: | 82 | curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/kustomize/${{ env.KUSTOMIZE_VERSION }}/hack/install_kustomize.sh" | bash 83 | sudo mv kustomize ${{ env.BIN_PATH }}/kustomize 84 | kustomize version 85 | 86 | - name: Verify cluster connectivity 87 | run: | 88 | kubectl cluster-info kwok 89 | kubectl get nodes 90 | 91 | - name: Add Helm repositories 92 | run: | 93 | bash .github/scripts/helm-argo-add.sh 94 | 95 | - name: Create test namespaces 96 | run: | 97 | source .github/scripts/functions.sh 98 | for ns in $(get_namespaces); do 99 | kubectl create namespace ${ns} 100 | done 101 | 102 | # Placeholder for iterative helm operations 103 | # TODO: Define specific helm install and template operations 104 | - name: Run Helm Operations (Placeholder) 105 | run: | 106 | echo "=== Helm Operations Placeholder ===" 107 | echo "This step will be expanded with specific helm install and template operations" 108 | echo "" 109 | echo "Examples of operations to be implemented:" 110 | echo "- helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true" 111 | echo "- helm template sealed-secrets sealed-secrets/sealed-secrets --namespace sealed-secrets | kubectl apply -f -" 112 | echo "" 113 | echo "Available helm repos:" 114 | helm repo list 115 | echo "" 116 | echo "Cluster is ready for helm operations!" 117 | 118 | - name: Validate cluster state 119 | run: | 120 | kubectl get all --all-namespaces 121 | kubectl get crd 2>/dev/null || echo "No CRDs installed yet" 122 | 123 | - name: Cleanup 124 | if: always() 125 | run: | 126 | kwokctl delete cluster || echo "Cluster already deleted" 127 | -------------------------------------------------------------------------------- /kubernetes/readme.md: -------------------------------------------------------------------------------- 1 | # Temporary Setup Commands 2 | 3 | > [!NOTE] 4 | > These commands will be wrapped behind GoTasks in the future. 5 | 6 | ## Install Core Required Resources 7 | 8 | ```bash 9 | # Add the Cilium Helm repository and update 10 | helm repo add cilium https://helm.cilium.io/ 11 | helm repo update 12 | 13 | helm upgrade --install cilium cilium/cilium \ 14 | --namespace=kube-system --version 1.17.5 \ 15 | --values kubernetes/core/kube-system/cilium/values.yaml 16 | 17 | sleep 20 18 | # Set up the BGP config 19 | kubectl apply --server-side -k kubernetes/core/kube-system/cilium/bgp 20 | 21 | # Set the Cert Manager version 22 | export CERT_MANAGER_VERSION="v1.17.1" 23 | 24 | # Add the Cert Manager Helm repository and update 25 | kubectl apply --server-side \ 26 | -f "https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.crds.yaml" 27 | 28 | ## Gateway API 29 | kubectl apply --server-side -k kubernetes/core/gateway-api 30 | 31 | # Install Cilium 32 | helm upgrade --install cilium cilium/cilium \ 33 | --namespace=kube-system --version 1.17.5 \ 34 | --values kubernetes/core/kube-system/cilium/values.yaml 35 | 36 | sleep 20 37 | 38 | # Add the CoreDNS Helm repository and update 39 | helm repo add coredns https://coredns.github.io/helm 40 | helm repo update 41 | 42 | # Install CoreDNS 43 | helm upgrade --install coredns coredns/coredns \ 44 | --namespace=kube-system --version 1.43.0 \ 45 | --values kubernetes/core/kube-system/coredns/values.yaml 46 | 47 | # Add the Jetstack Helm repository and update 48 | helm repo add jetstack https://charts.jetstack.io 49 | helm repo update 50 | 51 | # Install Cert Manager 52 | helm upgrade --install cert-manager jetstack/cert-manager \ 53 | --create-namespace --namespace cert-manager \ 54 | --version ${CERT_MANAGER_VERSION} 55 | ``` 56 | 57 | ## Istio 58 | 59 | ```bash 60 | # Set the Istio Version 61 | export ISTIO_VERSION=1.26.2 62 | # Add the Istio Helm repository and update 63 | helm repo add istio https://istio-release.storage.googleapis.com/charts 64 | helm repo update 65 | 66 | # Install Istio 67 | helm upgrade --install istio-base istio/base \ 68 | --create-namespace --namespace istio-system \ 69 | --version ${ISTIO_VERSION} \ 70 | --values kubernetes/core/istio-system/istio-base.values.yaml 71 | 72 | # Install Istiod 73 | helm upgrade --install istiod istio/istiod -n istio-system \ 74 | --version ${ISTIO_VERSION} \ 75 | --values kubernetes/core/istio-system/istiod.values.yaml \ 76 | --wait 77 | 78 | # Install Istio CNI 79 | helm upgrade --install istio-cni istio/cni \ 80 | --namespace istio-system \ 81 | --version ${ISTIO_VERSION} \ 82 | --values kubernetes/core/istio-system/cni.values.yaml \ 83 | --wait 84 | 85 | # Install Istio ZTunnel 86 | helm upgrade --install istio-ztunnel istio/ztunnel \ 87 | --namespace istio-system \ 88 | --version ${ISTIO_VERSION} \ 89 | --values kubernetes/core/istio-system/ztunnel.values.yaml \ 90 | --wait 91 | 92 | # Install Istio Gateway API 93 | helm upgrade --install istio-ingress istio/gateway \ 94 | --version ${ISTIO_VERSION} \ 95 | --create-namespace -n istio-ingress --wait 96 | ``` 97 | 98 | ## Metrics Server 99 | 100 | ```bash 101 | # Add the Metrics Server Helm repository and update 102 | helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/ 103 | helm repo update 104 | 105 | # Install the Metrics Server 106 | helm upgrade --install metrics-server metrics-server/metrics-server \ 107 | --namespace kube-system --version 3.12.2 \ 108 | --values kubernetes/core/kube-system/metrics-server/values.yaml 109 | ``` 110 | 111 | ## Sealed Secrets 112 | 113 | ```bash 114 | # Add the Sealed Secrets Helm repository and update 115 | helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets 116 | helm repo update 117 | 118 | # Create the Sealed Secrets namespace 119 | kubectl create namespace sealed-secrets 120 | 121 | # Create the Sealed Secrets key 122 | kubectl create secret tls sealed-secrets-key \ 123 | --cert=./keys/sealed-secret.crt \ 124 | --key=./keys/sealed-secret.key \ 125 | --namespace sealed-secrets 126 | 127 | # Label the Sealed Secrets key for the Sealed Secrets controller 128 | kubectl label secret/sealed-secrets-key \ 129 | --namespace sealed-secrets \ 130 | sealedsecrets.bitnami.com/sealed-secrets-key=true 131 | 132 | # Install Sealed Secrets 133 | helm upgrade --install sealed-secrets sealed-secrets/sealed-secrets \ 134 | --namespace sealed-secrets \ 135 | --version 2.17.2 --values kubernetes/core/sealed-secrets/values.yaml 136 | ``` 137 | -------------------------------------------------------------------------------- /kubernetes/services/github-action-runners/runners/gh-app-creds.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: bitnami.com/v1alpha1 3 | kind: SealedSecret 4 | metadata: 5 | creationTimestamp: null 6 | name: gh-app-goodmannershosting 7 | namespace: github 8 | spec: 9 | encryptedData: 10 | github_app_id: AgBe9/zjrL9mLgXaTVQFZueU0pM632rixGfh9wMjZE3w7TmS9pIuhlSBjpQFnc/V1N+JAjNY8mVNSdRr3wCr4TFRBeP4bUsFLNVxdYLMLm3ks5ddnvuDe2WbEJT1Rq4Jt6PweK174DZ/nvn7q1e0AtV7Y1M0anW87J9tiNe9IvEfzhHXfcChVqc8H9s8lbgQrt7vPQf9rgznaztY2BnHB6zY90b56VRqnQNq5LYo6DGriNSNjYPXhlhlTq2UEMTOWandNv540pNac7qSiEzNkKX+WRd2TPBEdz/iSNGQzh6XK4DEbkxA71JWH//43RogJKxTtn//csCED4rhgfDp/VAN8MQIPL4yfCambG/jwA7IY0H9tlwd69auHj4ANUiUpaIsbG5VF3cbrRaZSqctFp/w+3sJiLZAgzzso1qMi0ph3DujeVhq68Cx5xCh6ebgjqLN6sCOc/X31tfM3ZkDOJ9pEjAwL20NmUcBvikoH5vVL9VQFvati8Z+Fu7HKBhLxKtnaEeZp/St2hJqav8Q5egAGusqKu64IwEaQpV5K2UftOUos8STefBVWp6taBGstgLGC4tSloB3foj2CIOfQ9TMbXgV37ZOG6Hi0kTJZE6S1bmggVmj3fRZUJCsLbYVBHUMbOC30Z4YdzqMXTXunYk+pSKDtabV1ScfdwYI+ko2TXH14utgdZFAEQLvvEJN3iYOE4pMHLjx 11 | github_app_installation_id: AgADwMWNpSX+12g2SbeFaCNKXSaCb8W+iuV5puU7E5fRRDKVsccbM3+TXbuKeBMnfKH0x06QK5qo/Py1thT9uRkSDTSImknFZzHDZieHX3rZy1EDB1zaThHRoc3KvYWQpK9pCSdAdRabKPzB67Cj2iWeUvpVtWaXYmyPUFWTL09GTuI5Tivb5Un0eF5JPuV9wmEnhP1ycHpJABHnRNptvynuxR7gNcC24rHl/tjb6L50lLllK5b6Bl9E0AP/yqk0+njrSTSNh51gXaBKhUrdPRWUD8RbOfKg6aVINaTVVBtRG4hiOgI/l620ag6qlRqVrleyyKo9JpA+vj1N4agK6MGIpHJrqHsRL1XR6E7qG9N2s78OmuCPxficJBo0H/FzjuC0W6qqbg5UdYkc+JGWeU4Y5jHmyGBALgBfEU50RaxEv/JXWtJasMuXGTLk6FAo679rCout5QKmc0Hb1hqIpgeoq+xzEqJ1efvoSgPU71/nsKobJiQVbvXxAAdVX+vAAfuHF+QIbb3Kad4NdZ2RUIa1IPFSsm1I1jFbo3NtC+m6M+KczxJ+GdTk5hs27KWp8KyoZyQSCxlwB1va8gkkACXLf8EpK7DTsUbBOC1aV/P3077lKgjCTMVs3Lei1BU5+NCE5yWs3KjHzQ4zQURCLinHbld+Xa503SsxtHygr0gQxtDLfKPxTS+cHctjlUtRj+N0H8lHOadjGw== 12 | github_app_private_key: AgBx8Z6dyoniaspHacdFCwGGVIWy7bXGoI0shDN0oUou5b0f0nxX+C+LXLM/OMexg59PudutaDpEl/gKfs5glfjUFkQETN9iavQcsZIgA1Uf1r+kKmWT/uTv58Qc9jDRsllZq8ZDWVWIQM4HaBxRuZbWwKP2Hm3EPQneZnJkoVHaKer+N7zgRhp0/pcf6tGW4BIojjLamok/qB9+TVbVZXTEyIpyNDFN79OeIVnUM2APSjJDuNphA0g2rOVp+iqjvPqTbc1XVAZfmKv9W4rmYQT79Rwe+ZbaSriU0nlwQV6BIK8LfsJcew/VM2QCa/3IcspL+wehWIG8CSQgwNuSovigtHbCdRGBl6bZZAYxQVEV8u/mQ8QutDAik2MDmzfbAjurpygbUQqfZyUh1F75MjE84AnE22mB8C65sS2X1j9/5P/PSHJiCYS58y7mvHNn2wmuMpRwk5IL971klxZSsGEBdFKVFj7TiaG3HSnL2USSpKtplZGgmDM91DTBsQSixe36wJ4ha8EH5+mNGooCZw0q5nmb/rL9XxIynZiIMtLbUHT3CwyIWyOEPQiN/OiAQoMBzeT1y+nJ5YMzkYyncKIoCcnG9wwlzKQVDCVCkQGKMQjHv30AGhESl6lUZvg6w1FF0/WI3r0/9NshSiR2bW26qhUhv6p7GjNROKE97/92HDAUr45hsce9VIJhJNniKEY0vtVyAPWcwQvT8fKDSeSdHiKCXbhcTvCMbQDdwshnccG/ZcjIabaKMC2KLcJJaXFonEkGRtkMC1wFSGqFPpVhamYqAgIaeZo8G8nPwR6W4oJmbRz1ZAi4jHMIxT5aaTAKvVMnT4Aif8Uv+cUbzZToMXWS2ND8qUAitFNyATSUQDXRskBzE3w8p0xMA8pCs/9O1Y8blW6slOAw5pGqd2Ipl6auGGtSY0axG7eqRiGNgJ723EF5INJI3Z+L2Qp6jD/HDr2vFa7T7qwSHIMNcSQCFsraMfrLGFEmNhOdT5zU2GyS9j5DInzxrdt6FwHRsmh8XGGAQsB5kcgWWbJQHbbw+MeIHRO/4pXWL/k1QFFg41XjdhSbdyg3Qn19F+tu6dFdV1cW88kwcNrM2wVoB6ZxXWMgt+8EHQl2SyvOqEtgJmab1NnfHR5bsPzKIR3dVsRYfYOLoeLXEO+CF/SoNURoZQgG5Pu/fGMhdP+mqs/e11Gn8G4tSub2ZjMkrbY/ZRipKs+6gtISoSYRvfrEcypgZR54Os4myEQCFZGYz7t41E6xRjEYGzJZkacel0RITs8x7X/vQX05ooc5ideFdYYB/SPkd9gThYeHkbIUuvrQtsnP98WRc+RhtF2cinxQh2NpCYtOHilmi15Mg0ezln3mWCLWuQG728qS4LpK/1Nz/9e8k8KDSMAT34vmXEB66t7Jg4SXUvj0TRY4Ek92V++aQUYzb+oqOORTbUbBJwTpk3rH3Fv3X6uUjWzER8h9JzleusBvnut06g+Yq3jrWEVTgzs+WK//PMj8Wr2sx5av+EwWgj0H+WdJypJJWFwA6oO7vDQAsR8Rotm9hm8Q+cED+77rTIzRGDWyd9GxgMmIgNIsMyAbH3BesmoX0XgK/0KucQx1MO5b6jmk1d38Dxmxw9tEGBj3MXl4wlHRVU/cb+zJk1o3QsxRXdIPAAYRfXhwOzuh95EYNj7sjNGKDfI0IXJBnKwWQMkT1QwCLhOLih4RqDO74nQnLcdqCWeuQtPNZhAVjzFY2iLs45Ck952rHCFggHEjScyHtsrrJvoaSApCg2Y+wypj2tZQsXpV0RanVbOmuWQs/mOas4vEI9cGFj1GA3//1posVAwdI1Zka7j9FGBWTHx7eAaiQMxANl9gonHf8ibDVHAzEmz28Y2BGca5Fz6E7ocPzPaJB6P8/eJCeJllh+kXj6n592BbSKqsgagbxGBB89mC8DOqU3hGsueZln/qQgkxrWmgpyTSldiYZX+/5eyg/Mauh2dOCmPufShJs8JzgF0Wt1ArSoZIAim4rBQ7kzMyEsMOiuHyF24buQ0zbDtOwD28AXCOyIBr0zLYo/SwknSVDLUDqkmFamoni8fDUWB51ly6c54YLmMw+kENMX9VUz7x0UTei9EEokuM0L7zQttuoJaGtwl2FsmLq+kzUQBAM/FCWUHmT38fKz4mf///05cqaHxNRnJDTygUGu9h5Vl+pucmYq+u+U/ItIqZLTqI+vXkvzzew/tXJdXTQMlqM5+bz9Q8oeoHATIDZXf3TxH8xhwbYG68VlSSStc8R+Rc0oXRQz6DyeeYuYQpJpiasP/kDfLLYpVCq0J9pmpO/CGl/S18LEDq96cuLTKYfHC0DPnlrkhiF6VOSABS2trNiqWjHpxVLSXeZ8n4Ey4NFSuGTrjkvq1JvQP4kIItGqWPPMe1jBAKD9HmQPHDbcFjCQFP7nT6q403tS3+L4sIqkl3BJrvHFTgSMB781w566Vjo4gmXv7LVUTjWs7RxXrUHpECfMFLp9R2k62aE2mzg5wNTianB6HDbysCbBu2FhweKeII9c0BXYriaGGBI1ALVrjFAISEzb63CTfo0SE1keugWsVz+oNC2XfiTOTp+H5jT4CNAWGkVzC2nocIoFKABEdvvO0KSBA7xoYj9o892w9lsOf7uTmAws8Ta4JGXNjqt4umOWsd4IzxumwjhfFgk2rY0mPJjkWrbBm0BXxBj8hBFyoiTV/stwLHF3xmkJhfCLSCgng4h2OD9CbyIpB1IGhzIIJsoCkWGEC+RBgcZVVkUewfxARXV72YNWe4t3O/pI4XohiiLOmH0JFCxN0iQtdG9FtojSYJXrcG71qXIzxcfA/xQhpbpJWVh1Bc3klMZb1rhVST1D7vPFgG0enb+QaszpgV6m36fTCv/PTN00awL9nCRDESWszc1sa4G/pc1psPT0OxQ0eDDd1o9Ex0b/P3 13 | template: 14 | metadata: 15 | creationTimestamp: null 16 | name: gh-app-goodmannershosting 17 | namespace: github 18 | type: Opaque 19 | --------------------------------------------------------------------------------