From 7524aa5f2ce0bb54d4bc9ccb7fa9a1812b26ea42 Mon Sep 17 00:00:00 2001 From: Celes Renata Date: Sat, 11 Apr 2026 12:21:49 -0700 Subject: [PATCH] phase 15: helm chart for stonks-oracle deployment --- .kiro/specs/stonks-oracle/tasks.md | 8 +- infra/helm/stonks-oracle/Chart.yaml | 9 + .../helm/stonks-oracle/templates/_helpers.tpl | 15 ++ .../stonks-oracle/templates/configmap.yaml | 11 + .../stonks-oracle/templates/deployments.yaml | 87 +++++++ .../stonks-oracle/templates/ghcr-secret.yaml | 12 + .../templates/hive-metastore.yaml | 140 ++++++++++ .../helm/stonks-oracle/templates/ingress.yaml | 29 +++ .../stonks-oracle/templates/namespace.yaml | 7 + .../templates/network-policies.yaml | 164 ++++++++++++ .../helm/stonks-oracle/templates/secrets.yaml | 51 ++++ .../stonks-oracle/templates/services.yaml | 16 ++ .../stonks-oracle/templates/superset.yaml | 145 +++++++++++ infra/helm/stonks-oracle/templates/trino.yaml | 122 +++++++++ infra/helm/stonks-oracle/values.yaml | 243 ++++++++++++++++++ 15 files changed, 1055 insertions(+), 4 deletions(-) create mode 100644 infra/helm/stonks-oracle/Chart.yaml create mode 100644 infra/helm/stonks-oracle/templates/_helpers.tpl create mode 100644 infra/helm/stonks-oracle/templates/configmap.yaml create mode 100644 infra/helm/stonks-oracle/templates/deployments.yaml create mode 100644 infra/helm/stonks-oracle/templates/ghcr-secret.yaml create mode 100644 infra/helm/stonks-oracle/templates/hive-metastore.yaml create mode 100644 infra/helm/stonks-oracle/templates/ingress.yaml create mode 100644 infra/helm/stonks-oracle/templates/namespace.yaml create mode 100644 infra/helm/stonks-oracle/templates/network-policies.yaml create mode 100644 infra/helm/stonks-oracle/templates/secrets.yaml create mode 100644 infra/helm/stonks-oracle/templates/services.yaml create mode 100644 infra/helm/stonks-oracle/templates/superset.yaml create mode 100644 infra/helm/stonks-oracle/templates/trino.yaml create mode 100644 infra/helm/stonks-oracle/values.yaml diff --git a/.kiro/specs/stonks-oracle/tasks.md b/.kiro/specs/stonks-oracle/tasks.md index 2878478..b87c909 100644 --- a/.kiro/specs/stonks-oracle/tasks.md +++ b/.kiro/specs/stonks-oracle/tasks.md @@ -142,22 +142,22 @@ - Commit all current changes with message `phase 14-15: docker build validation and helm deployment` - Push to main branch - _Requirements: N1_ -- [ ] 15.2 Validate GitHub Actions workflow builds containers +- [x] 15.2 Validate GitHub Actions workflow builds containers - Monitor the GitHub Actions run to confirm lint-and-test and build-services jobs succeed - Fix any CI failures and re-push if needed - _Requirements: N1_ -- [ ] 15.3 Create Helm chart for stonks-oracle deployment +- [x] 15.3 Create Helm chart for stonks-oracle deployment - Create `infra/helm/stonks-oracle/Chart.yaml` with chart metadata - Create `infra/helm/stonks-oracle/values.yaml` with configurable image tags, replica counts, resource limits, and environment references - Create Helm templates for all deployments, services, configmap, secrets, ingress, and network policies from existing K8s manifests - Add imagePullSecrets configuration for GHCR private registry access - Add a template for a Kubernetes Secret of type `kubernetes.io/dockerconfigjson` for GHCR authentication - _Requirements: N1, 8.2_ -- [ ] 15.4 Configure GHCR image pull authentication on the cluster +- [x] 15.4 Configure GHCR image pull authentication on the cluster - Create a `docker-registry` secret in the `stonks-oracle` namespace with GHCR credentials (using a GitHub PAT or deploy key) - Reference the imagePullSecret in all deployment specs via the Helm values - _Requirements: 8.2, N1_ -- [ ] 15.5 Deploy stonks-oracle to the cluster via Helm +- [-] 15.5 Deploy stonks-oracle to the cluster via Helm - Run `helm install` or `helm upgrade --install` targeting the `stonks-oracle` namespace - Verify all pods reach Running/Ready state - Verify services and ingress endpoints are reachable diff --git a/infra/helm/stonks-oracle/Chart.yaml b/infra/helm/stonks-oracle/Chart.yaml new file mode 100644 index 0000000..14f08b8 --- /dev/null +++ b/infra/helm/stonks-oracle/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: stonks-oracle +description: AI market intelligence and paper-trading platform +type: application +version: 0.1.0 +appVersion: "1.0.0" +maintainers: + - name: Celes Renata + email: celes@frameshift.net diff --git a/infra/helm/stonks-oracle/templates/_helpers.tpl b/infra/helm/stonks-oracle/templates/_helpers.tpl new file mode 100644 index 0000000..e8f1bbf --- /dev/null +++ b/infra/helm/stonks-oracle/templates/_helpers.tpl @@ -0,0 +1,15 @@ +{{/* +Common labels +*/}} +{{- define "stonks.labels" -}} +app.kubernetes.io/part-of: stonks-oracle +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }} +{{- end }} + +{{/* +Full image path for a service +*/}} +{{- define "stonks.image" -}} +{{ $.Values.imageRegistry }}/{{ .image }}:{{ $.Values.imageTag }} +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/configmap.yaml b/infra/helm/stonks-oracle/templates/configmap.yaml new file mode 100644 index 0000000..c8cfa1f --- /dev/null +++ b/infra/helm/stonks-oracle/templates/configmap.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: stonks-config + namespace: {{ .Values.namespace }} + labels: + {{- include "stonks.labels" . | nindent 4 }} +data: + {{- range $key, $val := .Values.config }} + {{ $key }}: {{ $val | quote }} + {{- end }} diff --git a/infra/helm/stonks-oracle/templates/deployments.yaml b/infra/helm/stonks-oracle/templates/deployments.yaml new file mode 100644 index 0000000..da165c6 --- /dev/null +++ b/infra/helm/stonks-oracle/templates/deployments.yaml @@ -0,0 +1,87 @@ +{{- range $name, $svc := .Values.services }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $name }} + namespace: {{ $.Values.namespace }} + labels: + app: {{ $name }} + {{- include "stonks.labels" $ | nindent 4 }} + stonks-oracle/tier: {{ $svc.tier }} +spec: + replicas: {{ $svc.replicas }} + selector: + matchLabels: + app: {{ $name }} + template: + metadata: + labels: + app: {{ $name }} + stonks-oracle/tier: {{ $svc.tier }} + spec: + automountServiceAccountToken: false + {{- if $.Values.imagePullSecrets.enabled }} + imagePullSecrets: + - name: {{ $.Values.imagePullSecrets.name }} + {{- end }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: {{ $name }} + image: {{ $.Values.imageRegistry }}/{{ $svc.image }}:{{ $.Values.imageTag }} + imagePullPolicy: {{ $.Values.imagePullPolicy }} + {{- if $svc.port }} + ports: + - containerPort: {{ $svc.port }} + {{- end }} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + envFrom: + - configMapRef: + name: stonks-config + {{- range $svc.secrets }} + - secretRef: + name: {{ . }} + {{- end }} + resources: + requests: + cpu: {{ $svc.resources.requests.cpu }} + memory: {{ $svc.resources.requests.memory }} + limits: + cpu: {{ $svc.resources.limits.cpu | quote }} + memory: {{ $svc.resources.limits.memory }} + {{- if $svc.probes }} + {{- if $svc.probes.readiness }} + readinessProbe: + httpGet: + path: {{ $svc.probes.readiness.path }} + port: {{ $svc.probes.readiness.port }} + initialDelaySeconds: {{ $svc.probes.readiness.initialDelay }} + periodSeconds: {{ $svc.probes.readiness.period }} + {{- end }} + {{- if $svc.probes.liveness }} + livenessProbe: + httpGet: + path: {{ $svc.probes.liveness.path }} + port: {{ $svc.probes.liveness.port }} + initialDelaySeconds: {{ $svc.probes.liveness.initialDelay }} + periodSeconds: {{ $svc.probes.liveness.period }} + {{- end }} + {{- end }} + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: + sizeLimit: 10Mi +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/ghcr-secret.yaml b/infra/helm/stonks-oracle/templates/ghcr-secret.yaml new file mode 100644 index 0000000..e1b8d0e --- /dev/null +++ b/infra/helm/stonks-oracle/templates/ghcr-secret.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.imagePullSecrets.enabled .Values.imagePullSecrets.createSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.imagePullSecrets.name }} + namespace: {{ .Values.namespace }} + labels: + {{- include "stonks.labels" . | nindent 4 }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ .Values.imagePullSecrets.dockerconfigjson }} +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/hive-metastore.yaml b/infra/helm/stonks-oracle/templates/hive-metastore.yaml new file mode 100644 index 0000000..ce9eea4 --- /dev/null +++ b/infra/helm/stonks-oracle/templates/hive-metastore.yaml @@ -0,0 +1,140 @@ +{{- if .Values.hiveMetastore.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hive-metastore + namespace: {{ .Values.namespace }} + labels: + app: hive-metastore + {{- include "stonks.labels" . | nindent 4 }} + stonks-oracle/tier: analytics +spec: + replicas: 1 + selector: + matchLabels: + app: hive-metastore + template: + metadata: + labels: + app: hive-metastore + stonks-oracle/tier: analytics + spec: + automountServiceAccountToken: false + {{- if .Values.imagePullSecrets.enabled }} + imagePullSecrets: + - name: {{ .Values.imagePullSecrets.name }} + {{- end }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + seccompProfile: + type: RuntimeDefault + initContainers: + - name: hive-config-init + image: busybox:1.36 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + command: ["sh", "-c"] + args: + - | + cat > /hive-config/core-site.xml < + + fs.s3a.endpointhttp://minio.minio-service.svc.cluster.local:80 + fs.s3a.access.key${MINIO_ACCESS_KEY} + fs.s3a.secret.key${MINIO_SECRET_KEY} + fs.s3a.path.style.accesstrue + fs.s3a.implorg.apache.hadoop.fs.s3a.S3AFileSystem + fs.s3a.connection.ssl.enabledfalse + + EOF + cat > /hive-config/metastore-site.xml < + + metastore.thrift.uristhrift://0.0.0.0:9083 + metastore.task.threads.alwaysorg.apache.hadoop.hive.metastore.events.EventCleanerTask + metastore.expression.proxyorg.apache.hadoop.hive.metastore.DefaultPartitionExpressionProxy + javax.jdo.option.ConnectionDriverNameorg.apache.derby.jdbc.EmbeddedDriver + javax.jdo.option.ConnectionURLjdbc:derby:/opt/hive/data/metastore_db;create=true + metastore.warehouse.dirs3a://stonks-lakehouse/warehouse + + EOF + env: + - name: MINIO_ACCESS_KEY + valueFrom: + secretKeyRef: + name: stonks-core-secrets + key: MINIO_ACCESS_KEY + - name: MINIO_SECRET_KEY + valueFrom: + secretKeyRef: + name: stonks-core-secrets + key: MINIO_SECRET_KEY + volumeMounts: + - name: hive-config + mountPath: /hive-config + containers: + - name: hive-metastore + image: apache/hive:4.0.0 + ports: + - containerPort: 9083 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + env: + - name: SERVICE_NAME + value: metastore + - name: DB_DRIVER + value: derby + volumeMounts: + - name: hive-data + mountPath: /opt/hive/data + - name: hive-config + mountPath: /opt/hive/conf/core-site.xml + subPath: core-site.xml + - name: hive-config + mountPath: /opt/hive/conf/metastore-site.xml + subPath: metastore-site.xml + resources: + requests: + cpu: {{ .Values.hiveMetastore.resources.requests.cpu }} + memory: {{ .Values.hiveMetastore.resources.requests.memory }} + limits: + cpu: {{ .Values.hiveMetastore.resources.limits.cpu | quote }} + memory: {{ .Values.hiveMetastore.resources.limits.memory }} + volumes: + - name: hive-data + persistentVolumeClaim: + claimName: hive-metastore-data + - name: hive-config + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: hive-metastore + namespace: {{ .Values.namespace }} +spec: + selector: + app: hive-metastore + ports: + - port: 9083 + targetPort: 9083 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: hive-metastore-data + namespace: {{ .Values.namespace }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.hiveMetastore.storageSize }} +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/ingress.yaml b/infra/helm/stonks-oracle/templates/ingress.yaml new file mode 100644 index 0000000..3e93569 --- /dev/null +++ b/infra/helm/stonks-oracle/templates/ingress.yaml @@ -0,0 +1,29 @@ +{{- if .Values.ingress.enabled }} +{{- range $key, $ing := .Values.ingress.hosts }} +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: stonks-{{ $key }} + namespace: {{ $.Values.namespace }} + annotations: + cert-manager.io/cluster-issuer: {{ $.Values.ingress.clusterIssuer }} +spec: + ingressClassName: {{ $.Values.ingress.className }} + tls: + - hosts: + - {{ $ing.host }} + secretName: stonks-{{ $key }}-tls + rules: + - host: {{ $ing.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ $ing.service }} + port: + number: {{ $ing.port }} +{{- end }} +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/namespace.yaml b/infra/helm/stonks-oracle/templates/namespace.yaml new file mode 100644 index 0000000..4bbca16 --- /dev/null +++ b/infra/helm/stonks-oracle/templates/namespace.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Values.namespace }} + labels: + {{- include "stonks.labels" . | nindent 4 }} + kubernetes.io/metadata.name: {{ .Values.namespace }} diff --git a/infra/helm/stonks-oracle/templates/network-policies.yaml b/infra/helm/stonks-oracle/templates/network-policies.yaml new file mode 100644 index 0000000..a7730f9 --- /dev/null +++ b/infra/helm/stonks-oracle/templates/network-policies.yaml @@ -0,0 +1,164 @@ +{{- if .Values.networkPolicies.enabled }} +# Default deny all ingress +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: {} + policyTypes: + - Ingress +--- +# Query API: accept from Traefik ingress +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-query-api-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + app: query-api + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + ports: + - protocol: TCP + port: 8000 +--- +# Symbol Registry API: accept from Traefik ingress +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-symbol-registry-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + app: symbol-registry-api + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + ports: + - protocol: TCP + port: 8000 +--- +# Risk Engine: accept from broker-adapter and query-api +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-risk-engine-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + app: risk-engine + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app: broker-adapter + - podSelector: + matchLabels: + app: query-api + ports: + - protocol: TCP + port: 8000 +--- +# Superset: accept from Traefik ingress +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-superset-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + app: superset + policyTypes: + - Ingress + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + ports: + - protocol: TCP + port: 8088 +--- +# Trino: accept from Superset, query-api, and Traefik +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-trino-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + app: trino + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app: superset + - podSelector: + matchLabels: + app: query-api + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + ports: + - protocol: TCP + port: 8080 +--- +# Hive Metastore: accept from Trino and lake-publisher +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-hive-metastore-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + app: hive-metastore + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app: trino + - podSelector: + matchLabels: + app: lake-publisher + ports: + - protocol: TCP + port: 9083 +--- +# Broker adapter: isolated — no inbound +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: deny-broker-adapter-ingress + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + app: broker-adapter + policyTypes: + - Ingress + ingress: [] +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/secrets.yaml b/infra/helm/stonks-oracle/templates/secrets.yaml new file mode 100644 index 0000000..3ca8de4 --- /dev/null +++ b/infra/helm/stonks-oracle/templates/secrets.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Secret +metadata: + name: stonks-core-secrets + namespace: {{ .Values.namespace }} + labels: + {{- include "stonks.labels" . | nindent 4 }} +type: Opaque +stringData: + {{- range $key, $val := .Values.secrets.core }} + {{ $key }}: {{ $val | quote }} + {{- end }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: stonks-broker-secrets + namespace: {{ .Values.namespace }} + labels: + {{- include "stonks.labels" . | nindent 4 }} +type: Opaque +stringData: + {{- range $key, $val := .Values.secrets.broker }} + {{ $key }}: {{ $val | quote }} + {{- end }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: stonks-market-secrets + namespace: {{ .Values.namespace }} + labels: + {{- include "stonks.labels" . | nindent 4 }} +type: Opaque +stringData: + {{- range $key, $val := .Values.secrets.market }} + {{ $key }}: {{ $val | quote }} + {{- end }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: stonks-dashboard-secrets + namespace: {{ .Values.namespace }} + labels: + {{- include "stonks.labels" . | nindent 4 }} +type: Opaque +stringData: + {{- range $key, $val := .Values.secrets.dashboard }} + {{ $key }}: {{ $val | quote }} + {{- end }} diff --git a/infra/helm/stonks-oracle/templates/services.yaml b/infra/helm/stonks-oracle/templates/services.yaml new file mode 100644 index 0000000..a22d674 --- /dev/null +++ b/infra/helm/stonks-oracle/templates/services.yaml @@ -0,0 +1,16 @@ +{{- range $name, $svc := .Values.services }} +{{- if $svc.port }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $name }} + namespace: {{ $.Values.namespace }} +spec: + selector: + app: {{ $name }} + ports: + - port: {{ $svc.port }} + targetPort: {{ $svc.port }} +{{- end }} +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/superset.yaml b/infra/helm/stonks-oracle/templates/superset.yaml new file mode 100644 index 0000000..2c4ce0f --- /dev/null +++ b/infra/helm/stonks-oracle/templates/superset.yaml @@ -0,0 +1,145 @@ +{{- if .Values.superset.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: superset + namespace: {{ .Values.namespace }} + labels: + app: superset + {{- include "stonks.labels" . | nindent 4 }} + stonks-oracle/tier: dashboard +spec: + replicas: 1 + selector: + matchLabels: + app: superset + template: + metadata: + labels: + app: superset + stonks-oracle/tier: dashboard + spec: + automountServiceAccountToken: false + {{- if .Values.imagePullSecrets.enabled }} + imagePullSecrets: + - name: {{ .Values.imagePullSecrets.name }} + {{- end }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: superset + image: apache/superset:latest + ports: + - containerPort: 8088 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + env: + - name: SUPERSET_SECRET_KEY + valueFrom: + secretKeyRef: + name: stonks-dashboard-secrets + key: SUPERSET_SECRET_KEY + - name: ADMIN_USERNAME + value: admin + - name: ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: stonks-dashboard-secrets + key: SUPERSET_ADMIN_PASSWORD + - name: ADMIN_EMAIL + value: admin@stonks.local + volumeMounts: + - name: superset-home + mountPath: /app/superset_home + - name: superset-config + mountPath: /app/pythonpath/superset_config.py + subPath: superset_config.py + resources: + requests: + cpu: {{ .Values.superset.resources.requests.cpu }} + memory: {{ .Values.superset.resources.requests.memory }} + limits: + cpu: {{ .Values.superset.resources.limits.cpu | quote }} + memory: {{ .Values.superset.resources.limits.memory }} + readinessProbe: + httpGet: + path: /health + port: 8088 + initialDelaySeconds: 30 + periodSeconds: 15 + volumes: + - name: superset-home + persistentVolumeClaim: + claimName: superset-data + - name: superset-config + configMap: + name: superset-config +--- +apiVersion: v1 +kind: Service +metadata: + name: superset + namespace: {{ .Values.namespace }} +spec: + selector: + app: superset + ports: + - port: 8088 + targetPort: 8088 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: superset-data + namespace: {{ .Values.namespace }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.superset.storageSize }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: superset-config + namespace: {{ .Values.namespace }} +data: + superset_config.py: | + import os + SECRET_KEY = os.getenv("SUPERSET_SECRET_KEY", "stonks-dev-secret-key-change-me") + SQLALCHEMY_DATABASE_URI = "trino://trino@trino.{{ .Values.namespace }}.svc.cluster.local:8080/lakehouse/stonks" + FEATURE_FLAGS = {"ENABLE_TEMPLATE_PROCESSING": True} + CACHE_CONFIG = { + "CACHE_TYPE": "RedisCache", + "CACHE_DEFAULT_TIMEOUT": 300, + "CACHE_KEY_PREFIX": "superset_", + "CACHE_REDIS_HOST": os.getenv("REDIS_HOST", "redis-master.redis-service.svc.cluster.local"), + "CACHE_REDIS_PORT": int(os.getenv("REDIS_PORT", "6379")), + "CACHE_REDIS_DB": 1, + } + PUBLIC_ROLE_LIKE = None + SESSION_COOKIE_HTTPONLY = True + SESSION_COOKIE_SECURE = True + SESSION_COOKIE_SAMESITE = "Lax" + TALISMAN_ENABLED = True + TALISMAN_CONFIG = { + "content_security_policy": { + "default-src": ["'self'"], + "img-src": ["'self'", "data:"], + "style-src": ["'self'", "'unsafe-inline'"], + "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'"], + }, + "force_https": False, + } + PREVENT_UNSAFE_DB_CONNECTIONS = True + ROW_LIMIT = 50000 + SQL_MAX_ROW = 100000 +{{- end }} diff --git a/infra/helm/stonks-oracle/templates/trino.yaml b/infra/helm/stonks-oracle/templates/trino.yaml new file mode 100644 index 0000000..5ebc3ea --- /dev/null +++ b/infra/helm/stonks-oracle/templates/trino.yaml @@ -0,0 +1,122 @@ +{{- if .Values.trino.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: trino + namespace: {{ .Values.namespace }} + labels: + app: trino + {{- include "stonks.labels" . | nindent 4 }} + stonks-oracle/tier: analytics +spec: + replicas: 1 + selector: + matchLabels: + app: trino + template: + metadata: + labels: + app: trino + stonks-oracle/tier: analytics + spec: + automountServiceAccountToken: false + {{- if .Values.imagePullSecrets.enabled }} + imagePullSecrets: + - name: {{ .Values.imagePullSecrets.name }} + {{- end }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + seccompProfile: + type: RuntimeDefault + initContainers: + - name: catalog-init + image: busybox:1.36 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + command: ["sh", "-c"] + args: + - | + cat > /catalog/iceberg.properties < /catalog/lakehouse.properties <