Add DEMO feature to the project

This commit is contained in:
Urtzi Alfaro
2025-10-03 14:09:34 +02:00
parent 1243c2ca6d
commit dc8221bd2f
77 changed files with 6251 additions and 1074 deletions

View File

@@ -0,0 +1,77 @@
apiVersion: v1
kind: Service
metadata:
name: demo-session-db-service
namespace: bakery-ia
labels:
app: demo-session-db
component: database
spec:
type: ClusterIP
ports:
- port: 5432
targetPort: 5432
protocol: TCP
name: postgres
selector:
app: demo-session-db
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: demo-session-db
namespace: bakery-ia
labels:
app: demo-session-db
component: database
spec:
serviceName: demo-session-db-service
replicas: 1
selector:
matchLabels:
app: demo-session-db
template:
metadata:
labels:
app: demo-session-db
component: database
spec:
containers:
- name: postgres
image: postgres:15-alpine
ports:
- containerPort: 5432
name: postgres
env:
- name: POSTGRES_DB
value: "demo_session_db"
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: database-secrets
key: DEMO_SESSION_DB_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: database-secrets
key: DEMO_SESSION_DB_PASSWORD
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 2Gi

View File

@@ -0,0 +1,84 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-session-service
namespace: bakery-ia
labels:
app: demo-session-service
component: demo-session
spec:
replicas: 2
selector:
matchLabels:
app: demo-session-service
template:
metadata:
labels:
app: demo-session-service
component: demo-session
spec:
serviceAccountName: demo-session-sa
containers:
- name: demo-session
image: bakery/demo-session-service:latest
ports:
- containerPort: 8000
name: http
env:
- name: SERVICE_NAME
value: "demo-session"
- name: DEMO_SESSION_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: DEMO_SESSION_DATABASE_URL
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secrets
key: REDIS_PASSWORD
- name: REDIS_URL
value: "redis://:$(REDIS_PASSWORD)@redis-service:6379/0"
- name: AUTH_SERVICE_URL
value: "http://auth-service:8000"
- name: TENANT_SERVICE_URL
value: "http://tenant-service:8000"
- name: INVENTORY_SERVICE_URL
value: "http://inventory-service:8000"
- name: RECIPES_SERVICE_URL
value: "http://recipes-service:8000"
- name: SALES_SERVICE_URL
value: "http://sales-service:8000"
- name: ORDERS_SERVICE_URL
value: "http://orders-service:8000"
- name: PRODUCTION_SERVICE_URL
value: "http://production-service:8000"
- name: SUPPLIERS_SERVICE_URL
value: "http://suppliers-service:8000"
- name: LOG_LEVEL
value: "INFO"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CLONE_JOB_IMAGE
value: "bakery/inventory-service:latest"
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 10
periodSeconds: 10

View File

@@ -0,0 +1,35 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: demo-session-sa
namespace: bakery-ia
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: demo-session-job-creator
namespace: bakery-ia
rules:
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["create", "get", "list", "watch", "delete"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: demo-session-job-creator-binding
namespace: bakery-ia
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: demo-session-job-creator
subjects:
- kind: ServiceAccount
name: demo-session-sa
namespace: bakery-ia

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: demo-session-service
namespace: bakery-ia
labels:
app: demo-session-service
component: demo-session
spec:
type: ClusterIP
ports:
- port: 8000
targetPort: 8000
protocol: TCP
name: http
selector:
app: demo-session-service

View File

@@ -0,0 +1,56 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: demo-session-cleanup
namespace: bakery-ia
labels:
app: demo-cleanup
component: maintenance
spec:
schedule: "0 * * * *" # Every hour
timeZone: "Europe/Madrid"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
concurrencyPolicy: Forbid
jobTemplate:
metadata:
labels:
app: demo-cleanup
spec:
template:
metadata:
labels:
app: demo-cleanup
spec:
containers:
- name: cleanup
image: bakery/demo-session-service:latest
command:
- python
- -c
- |
import asyncio
import httpx
async def cleanup():
async with httpx.AsyncClient() as client:
response = await client.post("http://demo-session-service:8000/api/demo/cleanup/run")
print(response.json())
asyncio.run(cleanup())
env:
- name: DEMO_SESSION_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: DEMO_SESSION_DATABASE_URL
- name: REDIS_URL
value: "redis://redis-service:6379/0"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "128Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "200m"
restartPolicy: OnFailure

View File

@@ -0,0 +1,55 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-clone-VIRTUAL_TENANT_ID
namespace: bakery-ia
labels:
app: demo-clone
component: runtime
spec:
ttlSecondsAfterFinished: 3600 # Clean up after 1 hour
backoffLimit: 2
template:
metadata:
labels:
app: demo-clone
spec:
restartPolicy: Never
containers:
- name: clone-data
image: bakery/inventory-service:latest # Uses inventory image which has all scripts
command: ["python", "/app/scripts/demo/clone_demo_tenant.py"]
env:
- name: VIRTUAL_TENANT_ID
value: "VIRTUAL_TENANT_ID"
- name: DEMO_ACCOUNT_TYPE
value: "DEMO_ACCOUNT_TYPE"
- name: INVENTORY_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: INVENTORY_DATABASE_URL
- name: SALES_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: SALES_DATABASE_URL
- name: ORDERS_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: ORDERS_DATABASE_URL
- name: TENANT_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: TENANT_DATABASE_URL
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"

View File

@@ -0,0 +1,68 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-ai-models
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "25"
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-ai-models
spec:
initContainers:
- name: wait-for-training-migration
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 30 seconds for training-migration to complete..."
sleep 30
- name: wait-for-inventory-seed
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 15 seconds for demo-seed-inventory to complete..."
sleep 15
containers:
- name: seed-ai-models
image: bakery/training-service:latest
command: ["python", "/app/scripts/demo/seed_demo_ai_models.py"]
env:
- name: TRAINING_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: TRAINING_DATABASE_URL
- name: TENANT_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: TENANT_DATABASE_URL
- name: INVENTORY_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: INVENTORY_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,58 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-inventory
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "15"
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-inventory
spec:
initContainers:
- name: wait-for-inventory-migration
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 30 seconds for inventory-migration to complete..."
sleep 30
- name: wait-for-tenant-seed
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 15 seconds for demo-seed-tenants to complete..."
sleep 15
containers:
- name: seed-inventory
image: bakery/inventory-service:latest
command: ["python", "/app/scripts/demo/seed_demo_inventory.py"]
env:
- name: INVENTORY_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: INVENTORY_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,29 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: demo-seed-sa
namespace: bakery-ia
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: demo-seed-role
namespace: bakery-ia
rules:
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: demo-seed-rolebinding
namespace: bakery-ia
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: demo-seed-role
subjects:
- kind: ServiceAccount
name: demo-seed-sa
namespace: bakery-ia

View File

@@ -0,0 +1,60 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-tenants
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "10"
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-tenants
spec:
initContainers:
- name: wait-for-tenant-migration
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 30 seconds for tenant-migration to complete..."
sleep 30
- name: wait-for-user-seed
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 15 seconds for demo-seed-users to complete..."
sleep 15
containers:
- name: seed-tenants
image: bakery/tenant-service:latest
command: ["python", "/app/scripts/demo/seed_demo_tenants.py"]
env:
- name: TENANT_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: TENANT_DATABASE_URL
- name: AUTH_SERVICE_URL
value: "http://auth-service:8000"
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -0,0 +1,50 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-seed-users
namespace: bakery-ia
labels:
app: demo-seed
component: initialization
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "5"
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: demo-seed-users
spec:
initContainers:
- name: wait-for-auth-migration
image: busybox:1.36
command:
- sh
- -c
- |
echo "Waiting 30 seconds for auth-migration to complete..."
sleep 30
containers:
- name: seed-users
image: bakery/auth-service:latest
command: ["python", "/app/scripts/demo/seed_demo_users.py"]
env:
- name: AUTH_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: AUTH_DATABASE_URL
- name: DEMO_MODE
value: "production"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure
serviceAccountName: demo-seed-sa

View File

@@ -30,6 +30,17 @@ resources:
- migrations/orders-migration-job.yaml
- migrations/production-migration-job.yaml
- migrations/alert-processor-migration-job.yaml
- migrations/demo-session-migration-job.yaml
# Demo initialization jobs
- jobs/demo-seed-rbac.yaml
- jobs/demo-seed-users-job.yaml
- jobs/demo-seed-tenants-job.yaml
- jobs/demo-seed-inventory-job.yaml
- jobs/demo-seed-ai-models-job.yaml
# Demo cleanup cronjob
- cronjobs/demo-cleanup-cronjob.yaml
# Infrastructure components
- components/databases/redis.yaml
@@ -52,6 +63,12 @@ resources:
- components/databases/production-db.yaml
- components/databases/alert-processor-db.yaml
# Demo session components
- components/demo-session/database.yaml
- components/demo-session/rbac.yaml
- components/demo-session/service.yaml
- components/demo-session/deployment.yaml
# Microservices
- components/auth/auth-service.yaml
- components/tenant/tenant-service.yaml
@@ -106,6 +123,8 @@ images:
newTag: latest
- name: bakery/alert-processor
newTag: latest
- name: bakery/demo-session-service
newTag: latest
- name: bakery/gateway
newTag: latest
- name: bakery/dashboard

View File

@@ -0,0 +1,49 @@
apiVersion: batch/v1
kind: Job
metadata:
name: demo-session-migration
namespace: bakery-ia
labels:
app.kubernetes.io/name: demo-session-migration
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: bakery-ia
spec:
backoffLimit: 3
template:
metadata:
labels:
app.kubernetes.io/name: demo-session-migration
app.kubernetes.io/component: migration
spec:
initContainers:
- name: wait-for-db
image: postgres:15-alpine
command: ["sh", "-c", "until pg_isready -h demo-session-db-service -p 5432; do sleep 2; done"]
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
containers:
- name: migrate
image: bakery/demo-session-service:latest
imagePullPolicy: Never
command: ["python", "/app/scripts/run_migrations.py", "demo_session"]
env:
- name: DEMO_SESSION_DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secrets
key: DEMO_SESSION_DATABASE_URL
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
restartPolicy: OnFailure

View File

@@ -23,6 +23,7 @@ data:
ORDERS_DB_USER: b3JkZXJzX3VzZXI= # orders_user
PRODUCTION_DB_USER: cHJvZHVjdGlvbl91c2Vy # production_user
ALERT_PROCESSOR_DB_USER: YWxlcnRfcHJvY2Vzc29yX3VzZXI= # alert_processor_user
DEMO_SESSION_DB_USER: ZGVtb19zZXNzaW9uX3VzZXI= # demo_session_user
# Database Passwords (base64 encoded from .env)
AUTH_DB_PASSWORD: YXV0aF9wYXNzMTIz # auth_pass123
@@ -39,6 +40,7 @@ data:
ORDERS_DB_PASSWORD: b3JkZXJzX3Bhc3MxMjM= # orders_pass123
PRODUCTION_DB_PASSWORD: cHJvZHVjdGlvbl9wYXNzMTIz # production_pass123
ALERT_PROCESSOR_DB_PASSWORD: YWxlcnRfcHJvY2Vzc29yX3Bhc3MxMjM= # alert_processor_pass123
DEMO_SESSION_DB_PASSWORD: ZGVtb19zZXNzaW9uX3Bhc3MxMjM= # demo_session_pass123
# Database URLs (base64 encoded)
AUTH_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vYXV0aF91c2VyOmF1dGhfcGFzczEyM0BhdXRoLWRiLXNlcnZpY2U6NTQzMi9hdXRoX2Ri # postgresql+asyncpg://auth_user:auth_pass123@auth-db-service:5432/auth_db
@@ -55,6 +57,7 @@ data:
ORDERS_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vb3JkZXJzX3VzZXI6b3JkZXJzX3Bhc3MxMjNAb3JkZXJzLWRiLXNlcnZpY2U6NTQzMi9vcmRlcnNfZGI= # postgresql+asyncpg://orders_user:orders_pass123@orders-db-service:5432/orders_db
PRODUCTION_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vcHJvZHVjdGlvbl91c2VyOnByb2R1Y3Rpb25fcGFzczEyM0Bwcm9kdWN0aW9uLWRiLXNlcnZpY2U6NTQzMi9wcm9kdWN0aW9uX2Ri # postgresql+asyncpg://production_user:production_pass123@production-db-service:5432/production_db
ALERT_PROCESSOR_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vYWxlcnRfcHJvY2Vzc29yX3VzZXI6YWxlcnRfcHJvY2Vzc29yX3Bhc3MxMjNAYWxlcnQtcHJvY2Vzc29yLWRiLXNlcnZpY2U6NTQzMi9hbGVydF9wcm9jZXNzb3JfZGI= # postgresql+asyncpg://alert_processor_user:alert_processor_pass123@alert-processor-db-service:5432/alert_processor_db
DEMO_SESSION_DATABASE_URL: cG9zdGdyZXNxbCthc3luY3BnOi8vZGVtb19zZXNzaW9uX3VzZXI6ZGVtb19zZXNzaW9uX3Bhc3MxMjNAZGVtby1zZXNzaW9uLWRiLXNlcnZpY2U6NTQzMi9kZW1vX3Nlc3Npb25fZGI= # postgresql+asyncpg://demo_session_user:demo_session_pass123@demo-session-db-service:5432/demo_session_db
---
apiVersion: v1