feat(lasuite): add Projects (Planka Kanban) service
Deploy Planka-based project management at projects.DOMAIN_SUFFIX: - ConfigMap with OIDC, S3, SMTP, La Gaufre widget config - Deployment + Service (init container for DB migrations, Sails on 1337) - OAuth2Client (client_secret_basic, redirect to /oidc-callback) - VaultDynamicSecret for DATABASE_URL, VaultStaticSecret for SECRET_KEY - Pingora route with websocket support (Socket.io) - Image overrides in both local and production overlays - TLS cert dnsNames updated for projects subdomain - Integration service.json updated with Projects entry - seaweedfs-s3-credentials rolloutRestartTargets includes projects
This commit is contained in:
@@ -272,6 +272,11 @@ data:
|
|||||||
prefix = "/__"
|
prefix = "/__"
|
||||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||||
|
|
||||||
|
[[routes]]
|
||||||
|
host_prefix = "projects"
|
||||||
|
backend = "http://projects.lasuite.svc.cluster.local:80"
|
||||||
|
websocket = true
|
||||||
|
|
||||||
[[routes]]
|
[[routes]]
|
||||||
host_prefix = "s3"
|
host_prefix = "s3"
|
||||||
backend = "http://seaweedfs-filer.storage.svc.cluster.local:8333"
|
backend = "http://seaweedfs-filer.storage.svc.cluster.local:8333"
|
||||||
|
|||||||
@@ -21,24 +21,39 @@ data:
|
|||||||
{
|
{
|
||||||
"services": [
|
"services": [
|
||||||
{
|
{
|
||||||
"name": "Reuniões",
|
"name": "Calendar",
|
||||||
"url": "https://meet.DOMAIN_SUFFIX",
|
"url": "https://cal.DOMAIN_SUFFIX",
|
||||||
"logo": "https://integration.DOMAIN_SUFFIX/logos/visio.svg?v=2"
|
"logo": "https://integration.DOMAIN_SUFFIX/logos/calendar.svg?v=1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Drive",
|
"name": "Drive",
|
||||||
"url": "https://drive.DOMAIN_SUFFIX",
|
"url": "https://drive.DOMAIN_SUFFIX",
|
||||||
"logo": "https://integration.DOMAIN_SUFFIX/logos/drive.svg?v=1"
|
"logo": "https://integration.DOMAIN_SUFFIX/logos/drive.svg?v=1"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Mail",
|
||||||
|
"url": "https://mail.DOMAIN_SUFFIX",
|
||||||
|
"logo": "https://integration.DOMAIN_SUFFIX/logos/mail.svg?v=1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Meet",
|
||||||
|
"url": "https://meet.DOMAIN_SUFFIX",
|
||||||
|
"logo": "https://integration.DOMAIN_SUFFIX/logos/visio.svg?v=2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Projects",
|
||||||
|
"url": "https://projects.DOMAIN_SUFFIX",
|
||||||
|
"logo": "https://integration.DOMAIN_SUFFIX/logos/projects.svg?v=1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Source Code",
|
||||||
|
"url": "https://src.DOMAIN_SUFFIX",
|
||||||
|
"logo": "https://integration.DOMAIN_SUFFIX/logos/docs.svg?v=1"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Account",
|
"name": "Account",
|
||||||
"url": "https://auth.DOMAIN_SUFFIX",
|
"url": "https://auth.DOMAIN_SUFFIX",
|
||||||
"logo": "https://integration.DOMAIN_SUFFIX/logos/account.svg?v=1"
|
"logo": "https://integration.DOMAIN_SUFFIX/logos/account.svg?v=1"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Calendário",
|
|
||||||
"url": "https://cal.DOMAIN_SUFFIX",
|
|
||||||
"logo": "https://integration.DOMAIN_SUFFIX/logos/calendar.svg?v=1"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ resources:
|
|||||||
- calendars-frontend-caddyfile.yaml
|
- calendars-frontend-caddyfile.yaml
|
||||||
- calendars-frontend-deployment.yaml
|
- calendars-frontend-deployment.yaml
|
||||||
- calendars-frontend-service.yaml
|
- calendars-frontend-service.yaml
|
||||||
|
- projects-config.yaml
|
||||||
|
- projects-deployment.yaml
|
||||||
|
|
||||||
patches:
|
patches:
|
||||||
# Rewrite hardcoded production integration URL + inject theme CSS in people-frontend
|
# Rewrite hardcoded production integration URL + inject theme CSS in people-frontend
|
||||||
|
|||||||
@@ -200,3 +200,23 @@ spec:
|
|||||||
tokenEndpointAuthMethod: client_secret_post
|
tokenEndpointAuthMethod: client_secret_post
|
||||||
secretName: oidc-calendars
|
secretName: oidc-calendars
|
||||||
skipConsent: true
|
skipConsent: true
|
||||||
|
---
|
||||||
|
# ── Projects (Kanban) ──────────────────────────────────────────────────────
|
||||||
|
apiVersion: hydra.ory.sh/v1alpha1
|
||||||
|
kind: OAuth2Client
|
||||||
|
metadata:
|
||||||
|
name: projects
|
||||||
|
namespace: lasuite
|
||||||
|
spec:
|
||||||
|
clientName: Projects
|
||||||
|
grantTypes:
|
||||||
|
- authorization_code
|
||||||
|
- refresh_token
|
||||||
|
responseTypes:
|
||||||
|
- code
|
||||||
|
scope: openid email profile
|
||||||
|
redirectUris:
|
||||||
|
- https://projects.DOMAIN_SUFFIX/oidc-callback
|
||||||
|
tokenEndpointAuthMethod: client_secret_basic
|
||||||
|
secretName: oidc-projects
|
||||||
|
skipConsent: true
|
||||||
|
|||||||
40
base/lasuite/projects-config.yaml
Normal file
40
base/lasuite/projects-config.yaml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: projects-config
|
||||||
|
namespace: lasuite
|
||||||
|
data:
|
||||||
|
BASE_URL: "https://projects.DOMAIN_SUFFIX"
|
||||||
|
TRUST_PROXY: "1"
|
||||||
|
NODE_ENV: "production"
|
||||||
|
|
||||||
|
# OIDC — Hydra as the identity provider
|
||||||
|
OIDC_ISSUER: "https://auth.DOMAIN_SUFFIX/"
|
||||||
|
OIDC_SCOPES: "openid email profile"
|
||||||
|
OIDC_ENFORCED: "true"
|
||||||
|
OIDC_IGNORE_USERNAME: "true"
|
||||||
|
OIDC_IGNORE_ROLES: "true"
|
||||||
|
OIDC_ADMIN_ROLES: "*"
|
||||||
|
OIDC_FULLNAME_ATTRIBUTES: "given_name,family_name"
|
||||||
|
|
||||||
|
# S3 file storage via SeaweedFS
|
||||||
|
S3_ENDPOINT: "http://seaweedfs-filer.storage.svc.cluster.local:8333"
|
||||||
|
S3_BUCKET: "projects"
|
||||||
|
S3_REGION: "us-east-1"
|
||||||
|
S3_FORCE_PATH_STYLE: "true"
|
||||||
|
|
||||||
|
# SMTP via in-cluster Postfix relay
|
||||||
|
SMTP_HOST: "postfix.lasuite.svc.cluster.local"
|
||||||
|
SMTP_PORT: "25"
|
||||||
|
SMTP_SECURE: "false"
|
||||||
|
SMTP_FROM: "Projects <noreply@DOMAIN_SUFFIX>"
|
||||||
|
|
||||||
|
# La Gaufre waffle menu widget
|
||||||
|
REACT_APP_LAGAUFRE_WIDGET_API_URL: "https://integration.DOMAIN_SUFFIX/api/v2/services.json"
|
||||||
|
REACT_APP_LAGAUFRE_WIDGET_PATH: "https://integration.DOMAIN_SUFFIX/api/v2/"
|
||||||
|
|
||||||
|
# Default language for new OIDC users (browser detection fallback if unset)
|
||||||
|
DEFAULT_LANGUAGE: "en-US"
|
||||||
|
|
||||||
|
# Permissions
|
||||||
|
ALLOW_ALL_TO_CREATE_PROJECTS: "true"
|
||||||
121
base/lasuite/projects-deployment.yaml
Normal file
121
base/lasuite/projects-deployment.yaml
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Planka-based Kanban project management — single container (SPA bundled into Sails backend).
|
||||||
|
# Image: src.DOMAIN_SUFFIX/studio/projects:latest
|
||||||
|
# Built from projects/Dockerfile
|
||||||
|
#
|
||||||
|
# Secrets injected via env vars:
|
||||||
|
# - projects-db-url (VaultDynamicSecret): DATABASE_URL
|
||||||
|
# - projects-app-secrets (VaultStaticSecret): SECRET_KEY
|
||||||
|
# - oidc-projects (Hydra Maester): CLIENT_ID, CLIENT_SECRET
|
||||||
|
# - seaweedfs-s3-credentials (VaultStaticSecret): S3_ACCESS_KEY, S3_SECRET_KEY
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: projects
|
||||||
|
namespace: lasuite
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: projects
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: projects
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: db-migrate
|
||||||
|
image: projects
|
||||||
|
command: ["node", "db/init.js"]
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: projects-config
|
||||||
|
env:
|
||||||
|
- name: DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: projects-db-url
|
||||||
|
key: url
|
||||||
|
- name: SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: projects-app-secrets
|
||||||
|
key: SECRET_KEY
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
|
requests:
|
||||||
|
memory: 128Mi
|
||||||
|
cpu: 50m
|
||||||
|
containers:
|
||||||
|
- name: projects
|
||||||
|
image: projects
|
||||||
|
command: ["node", "app.js", "--prod"]
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 1337
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: projects-config
|
||||||
|
env:
|
||||||
|
- name: DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: projects-db-url
|
||||||
|
key: url
|
||||||
|
- name: SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: projects-app-secrets
|
||||||
|
key: SECRET_KEY
|
||||||
|
- name: OIDC_CLIENT_ID
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: oidc-projects
|
||||||
|
key: CLIENT_ID
|
||||||
|
- name: OIDC_CLIENT_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: oidc-projects
|
||||||
|
key: CLIENT_SECRET
|
||||||
|
- name: S3_ACCESS_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: seaweedfs-s3-credentials
|
||||||
|
key: S3_ACCESS_KEY
|
||||||
|
- name: S3_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: seaweedfs-s3-credentials
|
||||||
|
key: S3_SECRET_KEY
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512Mi
|
||||||
|
requests:
|
||||||
|
memory: 256Mi
|
||||||
|
cpu: 50m
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 30
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: projects
|
||||||
|
namespace: lasuite
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: projects
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 1337
|
||||||
@@ -49,6 +49,8 @@ spec:
|
|||||||
name: messages-backend
|
name: messages-backend
|
||||||
- kind: Deployment
|
- kind: Deployment
|
||||||
name: messages-worker
|
name: messages-worker
|
||||||
|
- kind: Deployment
|
||||||
|
name: projects
|
||||||
destination:
|
destination:
|
||||||
name: seaweedfs-s3-credentials
|
name: seaweedfs-s3-credentials
|
||||||
create: true
|
create: true
|
||||||
@@ -637,3 +639,79 @@ spec:
|
|||||||
text: "{{ index .Secrets \"caldav-outbound-api-key\" }}"
|
text: "{{ index .Secrets \"caldav-outbound-api-key\" }}"
|
||||||
CALDAV_INTERNAL_API_KEY:
|
CALDAV_INTERNAL_API_KEY:
|
||||||
text: "{{ index .Secrets \"caldav-internal-api-key\" }}"
|
text: "{{ index .Secrets \"caldav-internal-api-key\" }}"
|
||||||
|
---
|
||||||
|
# Projects DB credentials from OpenBao database secrets engine (static role, 24h rotation).
|
||||||
|
apiVersion: secrets.hashicorp.com/v1beta1
|
||||||
|
kind: VaultDynamicSecret
|
||||||
|
metadata:
|
||||||
|
name: projects-db-url
|
||||||
|
namespace: lasuite
|
||||||
|
spec:
|
||||||
|
vaultAuthRef: vso-auth
|
||||||
|
mount: database
|
||||||
|
path: static-creds/projects
|
||||||
|
allowStaticCreds: true
|
||||||
|
refreshAfter: 5m
|
||||||
|
rolloutRestartTargets:
|
||||||
|
- kind: Deployment
|
||||||
|
name: projects
|
||||||
|
destination:
|
||||||
|
name: projects-db-url
|
||||||
|
create: true
|
||||||
|
overwrite: true
|
||||||
|
transformation:
|
||||||
|
excludeRaw: true
|
||||||
|
templates:
|
||||||
|
url:
|
||||||
|
text: "postgresql://{{ index .Secrets \"username\" }}:{{ index .Secrets \"password\" }}@postgres-rw.data.svc.cluster.local:5432/projects_db"
|
||||||
|
---
|
||||||
|
apiVersion: secrets.hashicorp.com/v1beta1
|
||||||
|
kind: VaultStaticSecret
|
||||||
|
metadata:
|
||||||
|
name: projects-app-secrets
|
||||||
|
namespace: lasuite
|
||||||
|
spec:
|
||||||
|
vaultAuthRef: vso-auth
|
||||||
|
mount: secret
|
||||||
|
type: kv-v2
|
||||||
|
path: projects
|
||||||
|
refreshAfter: 30s
|
||||||
|
rolloutRestartTargets:
|
||||||
|
- kind: Deployment
|
||||||
|
name: projects
|
||||||
|
destination:
|
||||||
|
name: projects-app-secrets
|
||||||
|
create: true
|
||||||
|
overwrite: true
|
||||||
|
transformation:
|
||||||
|
excludeRaw: true
|
||||||
|
templates:
|
||||||
|
SECRET_KEY:
|
||||||
|
text: "{{ index .Secrets \"secret-key\" }}"
|
||||||
|
---
|
||||||
|
# Postfix DKIM signing key from OpenBao KV.
|
||||||
|
apiVersion: secrets.hashicorp.com/v1beta1
|
||||||
|
kind: VaultStaticSecret
|
||||||
|
metadata:
|
||||||
|
name: postfix-dkim
|
||||||
|
namespace: lasuite
|
||||||
|
spec:
|
||||||
|
vaultAuthRef: vso-auth
|
||||||
|
mount: secret
|
||||||
|
type: kv-v2
|
||||||
|
path: postfix-dkim
|
||||||
|
refreshAfter: 1h
|
||||||
|
rolloutRestartTargets:
|
||||||
|
- kind: Deployment
|
||||||
|
name: postfix
|
||||||
|
destination:
|
||||||
|
name: postfix-dkim
|
||||||
|
create: true
|
||||||
|
overwrite: true
|
||||||
|
transformation:
|
||||||
|
excludeRaw: true
|
||||||
|
templates:
|
||||||
|
private.key:
|
||||||
|
text: "{{ index .Secrets \"private-key\" }}"
|
||||||
|
selector:
|
||||||
|
text: "{{ index .Secrets \"selector\" }}"
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ images:
|
|||||||
newName: src.DOMAIN_SUFFIX/studio/meet-frontend
|
newName: src.DOMAIN_SUFFIX/studio/meet-frontend
|
||||||
newTag: latest
|
newTag: latest
|
||||||
|
|
||||||
|
# Projects (Kanban) — built and pushed by `sunbeam build projects`
|
||||||
|
- name: projects
|
||||||
|
newName: src.DOMAIN_SUFFIX/studio/projects
|
||||||
|
newTag: latest
|
||||||
|
|
||||||
# Calendars — built from source and pushed to Gitea registry.
|
# Calendars — built from source and pushed to Gitea registry.
|
||||||
- name: calendars-backend
|
- name: calendars-backend
|
||||||
newName: src.DOMAIN_SUFFIX/studio/calendars-backend
|
newName: src.DOMAIN_SUFFIX/studio/calendars-backend
|
||||||
|
|||||||
@@ -71,3 +71,4 @@ spec:
|
|||||||
- integration.DOMAIN_SUFFIX
|
- integration.DOMAIN_SUFFIX
|
||||||
- livekit.DOMAIN_SUFFIX
|
- livekit.DOMAIN_SUFFIX
|
||||||
- cal.DOMAIN_SUFFIX
|
- cal.DOMAIN_SUFFIX
|
||||||
|
- projects.DOMAIN_SUFFIX
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ images:
|
|||||||
newName: src.DOMAIN_SUFFIX/studio/calendars-frontend
|
newName: src.DOMAIN_SUFFIX/studio/calendars-frontend
|
||||||
newTag: latest
|
newTag: latest
|
||||||
|
|
||||||
|
# Projects (Kanban) — built and pushed by `sunbeam build projects`
|
||||||
|
- name: projects
|
||||||
|
newName: src.DOMAIN_SUFFIX/studio/projects
|
||||||
|
newTag: latest
|
||||||
|
|
||||||
# Tuwunel Matrix homeserver — built and pushed by `sunbeam build tuwunel`
|
# Tuwunel Matrix homeserver — built and pushed by `sunbeam build tuwunel`
|
||||||
- name: tuwunel
|
- name: tuwunel
|
||||||
newName: src.DOMAIN_SUFFIX/studio/tuwunel
|
newName: src.DOMAIN_SUFFIX/studio/tuwunel
|
||||||
|
|||||||
Reference in New Issue
Block a user