From 096e8271f13a7d5c2053c6c8b475569299cb290d Mon Sep 17 00:00:00 2001 From: Ben Pedigo Date: Tue, 12 May 2026 08:27:46 -0700 Subject: [PATCH 1/4] first draft charts --- charts/catalog/Chart.yaml | 5 + charts/catalog/templates/cloudsql_secret.yaml | 11 +++ charts/catalog/templates/configmap.yaml | 14 +++ charts/catalog/templates/deployment.yaml | 92 +++++++++++++++++++ charts/catalog/templates/hpa.yaml | 18 ++++ charts/catalog/templates/ingress.yaml | 28 ++++++ charts/catalog/templates/secret.yaml | 15 +++ charts/catalog/templates/service.yaml | 11 +++ charts/catalog/values.yaml | 36 ++++++++ 9 files changed, 230 insertions(+) create mode 100644 charts/catalog/Chart.yaml create mode 100644 charts/catalog/templates/cloudsql_secret.yaml create mode 100644 charts/catalog/templates/configmap.yaml create mode 100644 charts/catalog/templates/deployment.yaml create mode 100644 charts/catalog/templates/hpa.yaml create mode 100644 charts/catalog/templates/ingress.yaml create mode 100644 charts/catalog/templates/secret.yaml create mode 100644 charts/catalog/templates/service.yaml create mode 100644 charts/catalog/values.yaml diff --git a/charts/catalog/Chart.yaml b/charts/catalog/Chart.yaml new file mode 100644 index 0000000..b83f42d --- /dev/null +++ b/charts/catalog/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: catalog +description: A Helm chart for CAVE Catalog service on Kubernetes +version: 0.1.0 +appVersion: "0.1.0" diff --git a/charts/catalog/templates/cloudsql_secret.yaml b/charts/catalog/templates/cloudsql_secret.yaml new file mode 100644 index 0000000..82aa670 --- /dev/null +++ b/charts/catalog/templates/cloudsql_secret.yaml @@ -0,0 +1,11 @@ +{{ $gs := .Values.cloudsql.googleSecret | required ".Values.cloudsql.googleSecret is required." }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: catalog-cloudsql-google-cloud-key +type: Opaque +stringData: + {{ $v := $gs }} + google-secret.json: {{ if kindIs "map" $v }}{{ $v | toJson | quote }}{{ else }}{{ $v | quote }}{{ end }} diff --git a/charts/catalog/templates/configmap.yaml b/charts/catalog/templates/configmap.yaml new file mode 100644 index 0000000..0cddc53 --- /dev/null +++ b/charts/catalog/templates/configmap.yaml @@ -0,0 +1,14 @@ +{{- $cloudsql_pw := .Values.cloudsql.password | required ".Values.cloudsql.password is required." }} +{{- $global_server := .Values.cluster.globalServer | required ".Values.cluster.globalServer is required." }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: catalog-config +data: + DATABASE_URL: "postgresql+asyncpg://{{ .Values.cloudsql.username }}:{{ .Values.cloudsql.password }}@127.0.0.1:{{ .Values.cloudsql.port | default "5432" }}/{{ .Values.cloudsql.database | default "cave_catalog" }}" + AUTH_SERVICE_URL: "{{ .Values.cluster.globalServer }}/auth" + MAT_ENGINE_URL: "{{ .Values.cluster.globalServer }}/materialize" + CAVECLIENT_SERVER_ADDRESS: "{{ .Values.cluster.globalServer }}" + DATASTACKS: {{ .Values.catalog.datastacks | toJson | quote }} + LOG_LEVEL: {{ .Values.catalog.logLevel | default "ERROR" | quote }} diff --git a/charts/catalog/templates/deployment.yaml b/charts/catalog/templates/deployment.yaml new file mode 100644 index 0000000..d2c056f --- /dev/null +++ b/charts/catalog/templates/deployment.yaml @@ -0,0 +1,92 @@ +{{- $global_server := .Values.cluster.globalServer | required ".Values.cluster.globalServer is required." }} +{{- $raw := .Values.catalog.tag | default .Chart.AppVersion -}} +{{- $tag := ternary $raw (printf "v%s" $raw) (hasPrefix "v" $raw) -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: catalog +spec: + selector: + matchLabels: + app: catalog + template: + metadata: + labels: + app: catalog + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/secrets: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + checksum/cloudsql: {{ include (print $.Template.BasePath "/cloudsql_secret.yaml") . | sha256sum }} + spec: + tolerations: + - key: "pool" + operator: "Equal" + value: "{{ .Values.cluster.standardPool }}" + effect: "NoSchedule" + nodeSelector: + cloud.google.com/gke-nodepool: {{ .Values.cluster.standardPool }} + volumes: + - name: catalog-config-volume + configMap: + name: catalog-config + - name: google-cloud-key + secret: + secretName: catalog-google-cloud-key + - name: cloudsql-instance-credentials-volume + secret: + secretName: catalog-cloudsql-google-cloud-key + containers: + - name: catalog + image: {{ .Values.cluster.dockerRegistry }}/cave-catalog:{{ $tag }} + imagePullPolicy: Always + ports: + - containerPort: 80 + volumeMounts: + - name: google-cloud-key + mountPath: /home/nginx/.cloudvolume/secrets + envFrom: + - configMapRef: + name: catalog-config + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /home/nginx/.cloudvolume/secrets/google-secret.json + - name: DAF_CREDENTIALS + value: /home/nginx/.cloudvolume/secrets/cave-secret.json + resources: + requests: + memory: {{ .Values.catalog.resources.requests.memory | default "256Mi" }} + cpu: {{ .Values.catalog.resources.requests.cpu | default "100m" }} + readinessProbe: + httpGet: + path: /catalog/health + port: 80 + initialDelaySeconds: 5 + timeoutSeconds: 1 + periodSeconds: 60 + livenessProbe: + httpGet: + path: /catalog/health + port: 80 + initialDelaySeconds: 15 + timeoutSeconds: 1 + periodSeconds: 60 + - name: cloudsql-proxy + image: gcr.io/cloudsql-docker/gce-proxy:1.33.6 + command: + [ + "/cloud_sql_proxy", + "-instances={{ .Values.cluster.googleProject}}:{{ .Values.cluster.googleRegion}}:{{ .Values.cloudsql.sqlInstanceName}}=tcp:{{ .Values.cloudsql.port | default "5432" }}", + "-credential_file=/secrets/cloudsql/google-secret.json", + ] + resources: + requests: + memory: 8Mi + cpu: 10m + securityContext: + runAsUser: 2 + allowPrivilegeEscalation: false + volumeMounts: + - name: cloudsql-instance-credentials-volume + mountPath: /secrets/cloudsql + readOnly: true diff --git a/charts/catalog/templates/hpa.yaml b/charts/catalog/templates/hpa.yaml new file mode 100644 index 0000000..f4a9f84 --- /dev/null +++ b/charts/catalog/templates/hpa.yaml @@ -0,0 +1,18 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: catalog-scaler +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: catalog + minReplicas: {{ .Values.catalog.minReplicas | default 1 }} + maxReplicas: {{ .Values.catalog.maxReplicas | default 3 }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 75 diff --git a/charts/catalog/templates/ingress.yaml b/charts/catalog/templates/ingress.yaml new file mode 100644 index 0000000..5691b34 --- /dev/null +++ b/charts/catalog/templates/ingress.yaml @@ -0,0 +1,28 @@ +{{- $domain := .Values.cluster.domainName | required ".Values.cluster.domainName is required." -}} +{{- $prefix := .Values.cluster.cluster_prefix | required ".Values.cluster.cluster_prefix is required." -}} +{{- $defaultHost := printf "%s.%s" $prefix $domain -}} +{{- $dnsEntries := .Values.cluster.dns_entries | default (list) -}} +{{- $raw := append (default (list) $dnsEntries) $defaultHost -}} +{{- $hosts := uniq $raw -}} +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: catalog-ingress + annotations: + kubernetes.io/ingress.class: nginx +spec: + ingressClassName: nginx + rules: + {{- range $hosts }} + - host: {{ . }} + http: + paths: + - path: /catalog + pathType: ImplementationSpecific + backend: + service: + name: catalog-service + port: + number: 80 + {{- end }} diff --git a/charts/catalog/templates/secret.yaml b/charts/catalog/templates/secret.yaml new file mode 100644 index 0000000..2686f40 --- /dev/null +++ b/charts/catalog/templates/secret.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Secret +metadata: + name: catalog-google-cloud-key +type: Opaque +{{ $list := .Values.catalog.secretFiles | default (list) }} +{{ if not (empty $list) }} +stringData: + {{ range $list }} + {{ $v := .value }} + {{ .name }}: {{ if kindIs "map" $v }}{{ $v | toJson | quote }}{{ else }}{{ $v | quote }}{{ end }} + {{ end }} +{{ else }} +stringData: {} +{{ end }} diff --git a/charts/catalog/templates/service.yaml b/charts/catalog/templates/service.yaml new file mode 100644 index 0000000..a08f15b --- /dev/null +++ b/charts/catalog/templates/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: catalog-service +spec: + type: NodePort + selector: + app: catalog + ports: + - port: 80 + targetPort: 80 diff --git a/charts/catalog/values.yaml b/charts/catalog/values.yaml new file mode 100644 index 0000000..c9ee39e --- /dev/null +++ b/charts/catalog/values.yaml @@ -0,0 +1,36 @@ +catalog: + # image tag; if empty defaults to Chart.appVersion + tag: "" + datastacks: + - "" + secretFiles: + - name: google-secret.json + value: "" + - name: cave-secret.json + value: "" + authEnabled: true + logLevel: "ERROR" + resources: + requests: + memory: "256Mi" + cpu: "100m" + minReplicas: 1 + maxReplicas: 3 + +cloudsql: + sqlInstanceName: "" + googleSecret: "" + username: "postgres" + password: "" + database: "cave_catalog" + port: "5432" + +cluster: + globalServer: "" + environment: "" + domainName: "" + googleProject: "" + googleRegion: "us-east1" + googleZone: "us-east1-b" + standardPool: "standard-pool" + dockerRegistry: "docker.io/caveconnectome" From 24ef0652af4df668ed1bc7081686b2295b1f55e6 Mon Sep 17 00:00:00 2001 From: Ben Pedigo Date: Tue, 12 May 2026 11:27:30 -0700 Subject: [PATCH 2/4] address feedback --- charts/catalog/templates/configmap.yaml | 3 +-- charts/catalog/templates/db_secret.yaml | 9 +++++++++ charts/catalog/templates/deployment.yaml | 6 +++--- charts/catalog/values.yaml | 3 ++- 4 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 charts/catalog/templates/db_secret.yaml diff --git a/charts/catalog/templates/configmap.yaml b/charts/catalog/templates/configmap.yaml index 0cddc53..28d8373 100644 --- a/charts/catalog/templates/configmap.yaml +++ b/charts/catalog/templates/configmap.yaml @@ -1,4 +1,3 @@ -{{- $cloudsql_pw := .Values.cloudsql.password | required ".Values.cloudsql.password is required." }} {{- $global_server := .Values.cluster.globalServer | required ".Values.cluster.globalServer is required." }} --- apiVersion: v1 @@ -6,9 +5,9 @@ kind: ConfigMap metadata: name: catalog-config data: - DATABASE_URL: "postgresql+asyncpg://{{ .Values.cloudsql.username }}:{{ .Values.cloudsql.password }}@127.0.0.1:{{ .Values.cloudsql.port | default "5432" }}/{{ .Values.cloudsql.database | default "cave_catalog" }}" AUTH_SERVICE_URL: "{{ .Values.cluster.globalServer }}/auth" MAT_ENGINE_URL: "{{ .Values.cluster.globalServer }}/materialize" CAVECLIENT_SERVER_ADDRESS: "{{ .Values.cluster.globalServer }}" + AUTH_ENABLED: "true" DATASTACKS: {{ .Values.catalog.datastacks | toJson | quote }} LOG_LEVEL: {{ .Values.catalog.logLevel | default "ERROR" | quote }} diff --git a/charts/catalog/templates/db_secret.yaml b/charts/catalog/templates/db_secret.yaml new file mode 100644 index 0000000..0a75a7a --- /dev/null +++ b/charts/catalog/templates/db_secret.yaml @@ -0,0 +1,9 @@ +{{- $cloudsql_pw := .Values.cloudsql.password | required ".Values.cloudsql.password is required." }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: catalog-db-secret +type: Opaque +stringData: + DATABASE_URL: "postgresql+asyncpg://{{ .Values.cloudsql.username }}:{{ .Values.cloudsql.password }}@127.0.0.1:{{ .Values.cloudsql.port | default "5432" }}/{{ .Values.cloudsql.database | default "cave_catalog" }}" diff --git a/charts/catalog/templates/deployment.yaml b/charts/catalog/templates/deployment.yaml index d2c056f..ea1f731 100644 --- a/charts/catalog/templates/deployment.yaml +++ b/charts/catalog/templates/deployment.yaml @@ -18,6 +18,7 @@ spec: checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} checksum/secrets: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} checksum/cloudsql: {{ include (print $.Template.BasePath "/cloudsql_secret.yaml") . | sha256sum }} + checksum/db-secret: {{ include (print $.Template.BasePath "/db_secret.yaml") . | sha256sum }} spec: tolerations: - key: "pool" @@ -27,9 +28,6 @@ spec: nodeSelector: cloud.google.com/gke-nodepool: {{ .Values.cluster.standardPool }} volumes: - - name: catalog-config-volume - configMap: - name: catalog-config - name: google-cloud-key secret: secretName: catalog-google-cloud-key @@ -48,6 +46,8 @@ spec: envFrom: - configMapRef: name: catalog-config + - secretRef: + name: catalog-db-secret env: - name: GOOGLE_APPLICATION_CREDENTIALS value: /home/nginx/.cloudvolume/secrets/google-secret.json diff --git a/charts/catalog/values.yaml b/charts/catalog/values.yaml index c9ee39e..d634f7a 100644 --- a/charts/catalog/values.yaml +++ b/charts/catalog/values.yaml @@ -8,7 +8,6 @@ catalog: value: "" - name: cave-secret.json value: "" - authEnabled: true logLevel: "ERROR" resources: requests: @@ -29,6 +28,8 @@ cluster: globalServer: "" environment: "" domainName: "" + cluster_prefix: "" + dns_entries: [] googleProject: "" googleRegion: "us-east1" googleZone: "us-east1-b" From dc007d0d27e0b2da795135c4afdf0cce5974dd28 Mon Sep 17 00:00:00 2001 From: Ben Pedigo Date: Tue, 12 May 2026 11:27:45 -0700 Subject: [PATCH 3/4] more feedback --- charts/catalog/templates/configmap.yaml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/charts/catalog/templates/configmap.yaml b/charts/catalog/templates/configmap.yaml index 28d8373..7849739 100644 --- a/charts/catalog/templates/configmap.yaml +++ b/charts/catalog/templates/configmap.yaml @@ -1,4 +1,8 @@ -{{- $global_server := .Values.cluster.globalServer | required ".Values.cluster.globalServer is required." }} +{ + { + - $global_server := .Values.cluster.globalServer | required ".Values.cluster.globalServer is required.", + }, +} --- apiVersion: v1 kind: ConfigMap @@ -9,5 +13,5 @@ data: MAT_ENGINE_URL: "{{ .Values.cluster.globalServer }}/materialize" CAVECLIENT_SERVER_ADDRESS: "{{ .Values.cluster.globalServer }}" AUTH_ENABLED: "true" - DATASTACKS: {{ .Values.catalog.datastacks | toJson | quote }} - LOG_LEVEL: {{ .Values.catalog.logLevel | default "ERROR" | quote }} + DATASTACKS: { { .Values.catalog.datastacks | toJson | quote } } + LOG_LEVEL: { { .Values.catalog.logLevel | default "ERROR" | quote } } From bfff19e649e56f983cf10b302872a30e723e4cb0 Mon Sep 17 00:00:00 2001 From: Ben Pedigo Date: Tue, 12 May 2026 11:45:14 -0700 Subject: [PATCH 4/4] fix formatting --- charts/catalog/templates/configmap.yaml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/charts/catalog/templates/configmap.yaml b/charts/catalog/templates/configmap.yaml index 7849739..28d8373 100644 --- a/charts/catalog/templates/configmap.yaml +++ b/charts/catalog/templates/configmap.yaml @@ -1,8 +1,4 @@ -{ - { - - $global_server := .Values.cluster.globalServer | required ".Values.cluster.globalServer is required.", - }, -} +{{- $global_server := .Values.cluster.globalServer | required ".Values.cluster.globalServer is required." }} --- apiVersion: v1 kind: ConfigMap @@ -13,5 +9,5 @@ data: MAT_ENGINE_URL: "{{ .Values.cluster.globalServer }}/materialize" CAVECLIENT_SERVER_ADDRESS: "{{ .Values.cluster.globalServer }}" AUTH_ENABLED: "true" - DATASTACKS: { { .Values.catalog.datastacks | toJson | quote } } - LOG_LEVEL: { { .Values.catalog.logLevel | default "ERROR" | quote } } + DATASTACKS: {{ .Values.catalog.datastacks | toJson | quote }} + LOG_LEVEL: {{ .Values.catalog.logLevel | default "ERROR" | quote }}