From 868e8465cea3c75d73106eb634a93f9e6a1d1ce4 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Mon, 16 Feb 2026 13:35:43 +0100 Subject: [PATCH] updated hub yaml --- manifests/hub.yaml | 83 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/manifests/hub.yaml b/manifests/hub.yaml index 96fc6fa..8f974b5 100644 --- a/manifests/hub.yaml +++ b/manifests/hub.yaml @@ -6,12 +6,47 @@ # a centralized overview dashboard for the operator (Viktor). # # Namespace: felhom-system (shared with healthchecks and other felhom infra) +# +# PREREQUISITES: +# 1. Build and push the hub image: +# cd ~/build/felhom-hub && ./build.sh 0.1.0 --push +# +# 2. Generate a bcrypt password hash for dashboard login: +# htpasswd -nbBC 10 "" "your-password" | cut -d: -f2 +# Update the ConfigMap password_hash field below. +# +# 3. Generate a report API key (shared secret for controllers): +# openssl rand -hex 32 +# Update the ConfigMap report_api_key field below. +# Then add the same key to each customer's controller.yaml: +# hub: +# enabled: true +# url: "https://hub.felhom.eu" +# api_key: "" +# +# 4. Apply this manifest: +# kubectl apply -f manifests/hub.yaml +# +# 5. Configure DNS: +# Add hub.felhom.eu → k3s cluster IP in Cloudflare +# +# DEBUGGING: +# kubectl logs -n felhom-system deploy/hub -f +# kubectl exec -it -n felhom-system deploy/hub -- ls /data/ +# kubectl describe ingress -n felhom-system hub + +# ============================================================================= +# PERSISTENT STORAGE +# ============================================================================= --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: hub-data namespace: felhom-system + labels: + app: hub + recurring-job-group.longhorn.io/default: disabled spec: accessModes: - ReadWriteOnce @@ -19,6 +54,10 @@ spec: resources: requests: storage: 1Gi + +# ============================================================================= +# CONFIGURATION +# ============================================================================= --- apiVersion: v1 kind: ConfigMap @@ -28,8 +67,13 @@ metadata: data: hub.yaml: | auth: + # Bcrypt hash for dashboard login (Viktor only) + # Generate: htpasswd -nbBC 10 "" "your-password" | cut -d: -f2 password_hash: "" api: + # Shared secret for controller → hub report push + # Generate: openssl rand -hex 32 + # Must match hub.api_key in each customer's controller.yaml report_api_key: "" retention: max_days: 90 @@ -39,6 +83,10 @@ data: server: listen: ":8080" data_dir: "/data" + +# ============================================================================= +# DEPLOYMENT +# ============================================================================= --- apiVersion: apps/v1 kind: Deployment @@ -49,6 +97,8 @@ metadata: app: hub spec: replicas: 1 + strategy: + type: Recreate selector: matchLabels: app: hub @@ -62,6 +112,10 @@ spec: image: gitea.dooplex.hu/admin/felhom-hub:latest ports: - containerPort: 8080 + name: http + env: + - name: TZ + value: "Europe/Budapest" resources: requests: memory: "64Mi" @@ -74,18 +128,24 @@ spec: mountPath: /data - name: config mountPath: /etc/felhom-hub + # NOTE: When password_hash is set, GET / returns 401 for unauthenticated + # requests. The httpGet probe accepts 200-399 only, so it would fail. + # TODO: Add a /healthz endpoint in the hub code that bypasses auth. + # For now, probes work because password_hash is empty (no auth). livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 5 periodSeconds: 30 + timeoutSeconds: 5 readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 3 periodSeconds: 10 + timeoutSeconds: 3 volumes: - name: data persistentVolumeClaim: @@ -93,18 +153,29 @@ spec: - name: config configMap: name: hub-config + +# ============================================================================= +# SERVICE +# ============================================================================= --- apiVersion: v1 kind: Service metadata: name: hub namespace: felhom-system + labels: + app: hub spec: selector: app: hub ports: - port: 8080 targetPort: 8080 + name: http + +# ============================================================================= +# INGRESS — hub.felhom.eu +# ============================================================================= --- apiVersion: networking.k8s.io/v1 kind: Ingress @@ -114,6 +185,16 @@ metadata: annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/proxy-body-size: "2m" + # Geo-restrict to Hungary (operator-only dashboard) + # NOTE: /api/v1/report must also be reachable — all customers are in HU + nginx.ingress.kubernetes.io/configuration-snippet: | + set $geo_allowed 0; + if ($remote_addr ~ "^192\.168\.") { set $geo_allowed 1; } + if ($remote_addr ~ "^10\.") { set $geo_allowed 1; } + if ($geoip2_country_code = "HU") { set $geo_allowed 1; } + if ($geo_allowed = 0) { + return 403 "Access restricted to Hungary"; + } spec: ingressClassName: nginx-internal tls: @@ -130,4 +211,4 @@ spec: service: name: hub port: - number: 8080 + number: 8080 \ No newline at end of file