updated hub yaml
This commit is contained in:
@@ -6,12 +6,47 @@
|
|||||||
# a centralized overview dashboard for the operator (Viktor).
|
# a centralized overview dashboard for the operator (Viktor).
|
||||||
#
|
#
|
||||||
# Namespace: felhom-system (shared with healthchecks and other felhom infra)
|
# 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: "<same-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
|
apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
name: hub-data
|
name: hub-data
|
||||||
namespace: felhom-system
|
namespace: felhom-system
|
||||||
|
labels:
|
||||||
|
app: hub
|
||||||
|
recurring-job-group.longhorn.io/default: disabled
|
||||||
spec:
|
spec:
|
||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteOnce
|
- ReadWriteOnce
|
||||||
@@ -19,6 +54,10 @@ spec:
|
|||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
storage: 1Gi
|
storage: 1Gi
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# CONFIGURATION
|
||||||
|
# =============================================================================
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
@@ -28,8 +67,13 @@ metadata:
|
|||||||
data:
|
data:
|
||||||
hub.yaml: |
|
hub.yaml: |
|
||||||
auth:
|
auth:
|
||||||
|
# Bcrypt hash for dashboard login (Viktor only)
|
||||||
|
# Generate: htpasswd -nbBC 10 "" "your-password" | cut -d: -f2
|
||||||
password_hash: ""
|
password_hash: ""
|
||||||
api:
|
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: ""
|
report_api_key: ""
|
||||||
retention:
|
retention:
|
||||||
max_days: 90
|
max_days: 90
|
||||||
@@ -39,6 +83,10 @@ data:
|
|||||||
server:
|
server:
|
||||||
listen: ":8080"
|
listen: ":8080"
|
||||||
data_dir: "/data"
|
data_dir: "/data"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# DEPLOYMENT
|
||||||
|
# =============================================================================
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -49,6 +97,8 @@ metadata:
|
|||||||
app: hub
|
app: hub
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: hub
|
app: hub
|
||||||
@@ -62,6 +112,10 @@ spec:
|
|||||||
image: gitea.dooplex.hu/admin/felhom-hub:latest
|
image: gitea.dooplex.hu/admin/felhom-hub:latest
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
|
name: http
|
||||||
|
env:
|
||||||
|
- name: TZ
|
||||||
|
value: "Europe/Budapest"
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
memory: "64Mi"
|
memory: "64Mi"
|
||||||
@@ -74,18 +128,24 @@ spec:
|
|||||||
mountPath: /data
|
mountPath: /data
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /etc/felhom-hub
|
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:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /
|
path: /
|
||||||
port: 8080
|
port: 8080
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 30
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 5
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /
|
path: /
|
||||||
port: 8080
|
port: 8080
|
||||||
initialDelaySeconds: 3
|
initialDelaySeconds: 3
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 3
|
||||||
volumes:
|
volumes:
|
||||||
- name: data
|
- name: data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
@@ -93,18 +153,29 @@ spec:
|
|||||||
- name: config
|
- name: config
|
||||||
configMap:
|
configMap:
|
||||||
name: hub-config
|
name: hub-config
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# SERVICE
|
||||||
|
# =============================================================================
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: hub
|
name: hub
|
||||||
namespace: felhom-system
|
namespace: felhom-system
|
||||||
|
labels:
|
||||||
|
app: hub
|
||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
app: hub
|
app: hub
|
||||||
ports:
|
ports:
|
||||||
- port: 8080
|
- port: 8080
|
||||||
targetPort: 8080
|
targetPort: 8080
|
||||||
|
name: http
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# INGRESS — hub.felhom.eu
|
||||||
|
# =============================================================================
|
||||||
---
|
---
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
@@ -114,6 +185,16 @@ metadata:
|
|||||||
annotations:
|
annotations:
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
nginx.ingress.kubernetes.io/proxy-body-size: "2m"
|
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:
|
spec:
|
||||||
ingressClassName: nginx-internal
|
ingressClassName: nginx-internal
|
||||||
tls:
|
tls:
|
||||||
|
|||||||
Reference in New Issue
Block a user