diff --git a/charts/llm-gateway/Chart.lock b/charts/llm-gateway/Chart.lock
new file mode 100644
index 00000000..a42121dd
--- /dev/null
+++ b/charts/llm-gateway/Chart.lock
@@ -0,0 +1,6 @@
+dependencies:
+- name: nats
+ repository: https://nats-io.github.io/k8s/helm/charts/
+ version: 1.1.6
+digest: sha256:d7139a23518bd17a525ab93874436431746026fdbcf299b89bfd0a19baea41ab
+generated: "2024-03-18T17:01:49.011124+05:30"
diff --git a/charts/llm-gateway/Chart.yaml b/charts/llm-gateway/Chart.yaml
new file mode 100644
index 00000000..3fb70355
--- /dev/null
+++ b/charts/llm-gateway/Chart.yaml
@@ -0,0 +1,11 @@
+apiVersion: v2
+name: llm-gateway
+version: 0.2.3-rc.1
+description: "LLM Gateway deployment chart"
+maintainers:
+ - name: truefoundry
+dependencies:
+ - name: nats
+ repository: https://nats-io.github.io/k8s/helm/charts/
+ version: 1.1.6
+ condition: nats.enabled
diff --git a/charts/llm-gateway/templates/_helpers.tpl b/charts/llm-gateway/templates/_helpers.tpl
new file mode 100644
index 00000000..4f5316fb
--- /dev/null
+++ b/charts/llm-gateway/templates/_helpers.tpl
@@ -0,0 +1,100 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create a default fully qualified app name.
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+ If release name contains chart name it will be used as a full name.
+ */}}
+{{- define "app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Create chart name and version as used by the chart label.
+ */}}
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Common labels
+ */}}
+{{- define "app.labels" -}}
+helm.sh/chart: {{ include "app.chart" . }}
+{{- range $name, $value := .Values.commonLabels }}
+{{ $name }}: {{ tpl $value $ | quote }}
+{{- end }}
+{{ include "app.selectorLabels" . }}
+{{- if .Values.imageTag }}
+app.kubernetes.io/version: {{ .Values.imageTag | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+ Selector labels
+ */}}
+{{- define "app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+ Create the name of the service account to use
+ */}}
+{{- define "app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Parse env from template
+ */}}
+{{- define "app.parseEnv" -}}
+{{ tpl (.Values.env | toYaml) . }}
+{{- end }}
+
+{{/*
+ Create the env file
+ */}}
+{{- define "app.env" }}
+{{- range $key, $val := (include "app.parseEnv" .) | fromYaml }}
+{{- if and $val (contains "${k8s-secret" ($val | toString)) }}
+{{- if eq (regexSplit "/" $val -1 | len) 2 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ $.Values.envSecretName }}
+ key: {{ index (regexSplit "/" $val -1) 1 | trimSuffix "}" }}
+{{- else if eq (regexSplit "/" $val -1 | len) 3 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ index (regexSplit "/" $val -1) 1 }}
+ key: {{ index (regexSplit "/" $val -1) 2 | trimSuffix "}" }}
+{{- else }}
+{{- fail "Invalid secret supplied" }}
+{{- end }}
+{{- else }}
+- name: {{ $key }}
+ value: {{ $val | quote }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/llm-gateway/templates/clickhouse-installation.yaml b/charts/llm-gateway/templates/clickhouse-installation.yaml
new file mode 100644
index 00000000..415a5848
--- /dev/null
+++ b/charts/llm-gateway/templates/clickhouse-installation.yaml
@@ -0,0 +1,111 @@
+{{- if .Values.clickhouse.enabled -}}
+apiVersion: "clickhouse.altinity.com/v1"
+kind: "ClickHouseInstallation"
+metadata:
+ name: {{ .Release.Name }}
+ annotations:
+ argocd.argoproj.io/sync-options: Prune=false,Delete=false
+spec:
+ defaults:
+ templates:
+ serviceTemplate: svc-template
+ configuration:
+ clusters:
+ - name: {{ .Release.Name }}
+ layout:
+ shardsCount: {{ .Values.clickhouse.shardsCount }}
+ replicasCount: {{ .Values.clickhouse.replicasCount }}
+ templates:
+ podTemplate: clickhouse-stable
+ dataVolumeClaimTemplate: clickhouse-data-volume
+ serviceTemplate: svc-template
+ zookeeper:
+ nodes:
+ - host: {{ tpl .Values.clickhouse.zookeeperHost . }}
+ port: {{ tpl .Values.clickhouse.zookeeperPort . }}
+ {{- if .Values.clickhouse.user }}
+ users:
+ {{ .Values.clickhouse.user }}/password: {{ required ".Values.clickhouse.password is required" .Values.clickhouse.password }}
+ {{ .Values.clickhouse.user }}/profile: default
+ {{ .Values.clickhouse.user }}/quota: default
+ {{ .Values.clickhouse.user }}/networks/ip:
+ - 0.0.0.0/0
+ - ::/0
+ {{- end }}
+ files:
+ config.d/named-collections.xml: |
+
+
+
+ {{- $natsURL := (tpl .Values.clickhouse.nats.url .) }}
+ {{- $natsSubjects := .Values.clickhouse.nats.subjects }}
+ {{- $natsUsername := .Values.clickhouse.nats.username }}
+ {{- $natsPassword := .Values.clickhouse.nats.password }}
+ {{ $natsURL }}
+ {{ $natsSubjects }}
+ {{ $natsUsername }}
+ {{ $natsPassword }}
+ JSONEachRow
+ best_effort
+
+
+
+ config.d/log_rotation.xml: |-
+
+
+ information
+ /var/log/clickhouse-server/clickhouse-server.log
+ /var/log/clickhouse-server/clickhouse-server.err.log
+ 100M
+ 5
+ 1
+
+
+ templates:
+ serviceTemplates:
+ - name: svc-template
+ generateName: clickhouse-{chi}
+ spec:
+ ports:
+ - name: http
+ port: 8123
+ - name: tcp
+ port: 9000
+ type: ClusterIP
+ podTemplates:
+ - name: clickhouse-stable
+ spec:
+ affinity:
+ podAntiAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchExpressions:
+ - key: clickhouse.altinity.com/cluster
+ operator: In
+ values:
+ - {{ .Release.Name }}
+ topologyKey: "kubernetes.io/hostname"
+ containers:
+ - name: clickhouse
+ image: {{ .Values.clickhouse.image }}
+ resources:
+ requests:
+ memory: {{ .Values.clickhouse.resources.requests.memory }}
+ cpu: {{ .Values.clickhouse.resources.requests.cpu }}
+ ephemeral-storage: {{ .Values.clickhouse.resources.requests.ephemeralStorage }}
+ limits:
+ memory: {{ .Values.clickhouse.resources.limits.memory }}
+ cpu: {{ .Values.clickhouse.resources.limits.cpu }}
+ ephemeral-storage: {{ .Values.clickhouse.resources.limits.ephemeralStorage }}
+ volumeClaimTemplates:
+ - name: clickhouse-data-volume
+ spec:
+ storageClassName: {{ .Values.clickhouse.storage.storageClassName }}
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: {{ .Values.clickhouse.storage.size }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/llm-gateway/templates/deployment.yaml b/charts/llm-gateway/templates/deployment.yaml
new file mode 100644
index 00000000..339e0d1f
--- /dev/null
+++ b/charts/llm-gateway/templates/deployment.yaml
@@ -0,0 +1,69 @@
+{{- if .Values.llmGatewayEnabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "app.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "app.labels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "app.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ env:
+ {{- include "app.env" . | trim | nindent 12 }}
+ image: "{{ .Values.imageRepository }}:{{ .Values.imageTag }}"
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.service.port }}
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- if .Values.healthcheck.enabled }}
+ livenessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.liveness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ readinessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.readiness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ {{- end }}
+ volumeMounts:
+ {{- toYaml .Values.extraVolumeMounts | nindent 12 }}
+ volumes:
+ {{- toYaml .Values.extraVolumes | nindent 8 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.topologySpreadConstraints }}
+ topologySpreadConstraints:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/llm-gateway/templates/ingress.yaml b/charts/llm-gateway/templates/ingress.yaml
new file mode 100644
index 00000000..1b0c28f3
--- /dev/null
+++ b/charts/llm-gateway/templates/ingress.yaml
@@ -0,0 +1,39 @@
+{{- if and .Values.llmGatewayEnabled .Values.ingress.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+{{- if .Values.ingress.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.ingress.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- end }}
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.ingress.labels }}
+ {{- toYaml .Values.ingress.labels | nindent 4 }}
+ {{- end }}
+spec:
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+ rules:
+ {{- range $host := .Values.ingress.hosts }}
+ - host: {{ $host }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ $serviceName }}
+ port:
+ number: {{ $servicePort }}
+
+ {{- end -}}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- toYaml .Values.ingress.tls | nindent 4 }}
+ {{- end -}}
+{{- end -}}
diff --git a/charts/llm-gateway/templates/nats-metrics-virtualservice.yaml b/charts/llm-gateway/templates/nats-metrics-virtualservice.yaml
new file mode 100644
index 00000000..42f6892f
--- /dev/null
+++ b/charts/llm-gateway/templates/nats-metrics-virtualservice.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.nats.natsMetricsServerHost }}
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+ name: "{{ .Release.Name }}-nats-metrics"
+spec:
+ hosts:
+ - {{ .Values.nats.natsMetricsServerHost | quote }}
+ gateways:
+ - {{ tpl .Values.nats.gatewayName . }}
+ http:
+ - route:
+ - destination:
+ host: {{ .Release.Name }}-nats
+ port:
+ number: 8222
+{{- end }}
\ No newline at end of file
diff --git a/charts/llm-gateway/templates/nats-virtualservice.yaml b/charts/llm-gateway/templates/nats-virtualservice.yaml
new file mode 100644
index 00000000..9a0efd68
--- /dev/null
+++ b/charts/llm-gateway/templates/nats-virtualservice.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.nats.natsServerHost }}
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+ name: "{{ .Release.Name }}-nats"
+spec:
+ hosts:
+ - {{ .Values.nats.natsServerHost | quote }}
+ gateways:
+ - {{ tpl .Values.nats.gatewayName . }}
+ http:
+ - route:
+ - destination:
+ host: {{ .Release.Name }}-nats
+ port:
+ number: 8080
+{{- end }}
\ No newline at end of file
diff --git a/charts/llm-gateway/templates/service.yaml b/charts/llm-gateway/templates/service.yaml
new file mode 100644
index 00000000..46bbe8db
--- /dev/null
+++ b/charts/llm-gateway/templates/service.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.llmGatewayEnabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: {{ .Values.service.port }}
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "app.selectorLabels" . | nindent 4 }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/llm-gateway/templates/serviceaccount.yaml b/charts/llm-gateway/templates/serviceaccount.yaml
new file mode 100644
index 00000000..13443a8e
--- /dev/null
+++ b/charts/llm-gateway/templates/serviceaccount.yaml
@@ -0,0 +1,18 @@
+{{- if and .Values.llmGatewayEnabled .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "app.serviceAccountName" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations:
+{{ tpl (toYaml . | indent 4) $ }}
+{{- end }}
+imagePullSecrets:
+{{- if .Values.global.existingTruefoundryImagePullSecretName }}
+ - name: {{ .Values.global.existingTruefoundryImagePullSecretName }}
+{{- else }}
+ - name: truefoundry-image-pull-secret
+{{- end }}
+{{- end }}
diff --git a/charts/llm-gateway/templates/virtualservice.yaml b/charts/llm-gateway/templates/virtualservice.yaml
new file mode 100644
index 00000000..d5d0feb0
--- /dev/null
+++ b/charts/llm-gateway/templates/virtualservice.yaml
@@ -0,0 +1,32 @@
+{{- if and .Values.llmGatewayEnabled .Values.istio.virtualservice.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.istio.io/v1beta1
+kind: VirtualService
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.istio.virtualservice.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.istio.virtualservice.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ namespace: {{ .Release.Namespace }}
+spec:
+ gateways:
+ {{- range .Values.istio.virtualservice.gateways}}
+ - {{ . }}
+ {{- end }}
+ hosts:
+ {{- range .Values.istio.virtualservice.hosts}}
+ - {{ . }}
+ {{- end }}
+ http:
+ - route:
+ - destination:
+ host: {{ include "app.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+ port:
+ number: {{ .Values.service.port }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/llm-gateway/values.yaml b/charts/llm-gateway/values.yaml
new file mode 100644
index 00000000..1ac6ee5b
--- /dev/null
+++ b/charts/llm-gateway/values.yaml
@@ -0,0 +1,200 @@
+global: {}
+llmGatewayEnabled: true
+imageRepository: truefoundrycloud/llm-gateway
+replicaCount: 1
+environmentName: default
+envSecretName: llm-gateway-env-secret
+imagePullPolicy: IfNotPresent
+nameOverride: ''
+fullnameOverride: ''
+podAnnotations: {}
+podSecurityContext: {}
+commonLabels: {}
+securityContext: {}
+healthcheck:
+ enabled: true
+ readiness:
+ port: 8787
+ path: /
+ liveness:
+ port: 8787
+ path: /
+resources:
+ limits:
+ cpu: 400m
+ memory: 512Mi
+ ephemeral-storage: 256Mi
+ requests:
+ cpu: 200m
+ memory: 256Mi
+ ephemeral-storage: 128Mi
+nodeSelector: {}
+tolerations: {}
+affinity: {}
+topologySpreadConstraints: {}
+ingress:
+ enabled: false
+ annotations: {}
+ labels: {}
+ ingressClassName: istio
+ tls: []
+ hosts: []
+istio:
+ virtualservice:
+ enabled: false
+ annotations: {}
+ gateways: []
+ hosts: []
+service:
+ type: ClusterIP
+ port: 8787
+ annotations: {}
+serviceAccount:
+ create: true
+ name: llm-gateway
+ annotations: {}
+extraVolumes: []
+extraVolumeMounts: []
+env:
+ TRUEFOUNDRY_PUBLIC_ENABLED: ''
+ SERVICEFOUNDRY_SERVER_URL: https://app.truefoundry.com/api/svc
+ SFY_USER_API_KEY: ${k8s-secret/truefoundry-creds/TFY_API_KEY}
+ TOGETHER_AI_API_KEY: ''
+ AUTH_SERVER_URL: https://auth.truefoundry.com
+ LOG_LEVEL: info
+ LOGGING_SINK_CONFIGURATION: ''
+ DEPLOYED_HOSTNAME: ''
+ CONTROL_PLANE_NATS_URL: ''
+imageTag: 3870a7350078cc00004d9c2c3ee7c8eec9b67393
+nats:
+ enabled: false
+ config:
+ nats:
+ port: 4222
+ merge:
+ authorization:
+ users:
+ - user: admin
+ password:
+ permissions:
+ publish:
+ - '>'
+ subscribe:
+ - '>'
+ - user: llm-gateway-request-logger
+ password:
+ permissions:
+ publish:
+ - tfy-model-logs.>
+ subscribe:
+ - '>'
+ - user: clickhouse-request-logs-reader
+ password:
+ permissions:
+ subscribe:
+ - tfy-model-logs.>
+ timeout: 5
+ cluster:
+ port: 6222
+ enabled: true
+ replicas: 5
+ monitor:
+ tls:
+ enabled: false
+ port: 8222
+ enabled: true
+ jetstream:
+ enabled: true
+ fileStore:
+ dir: /data
+ pvc:
+ size: 2Gi
+ enabled: true
+ storageClassName: ''
+ enabled: true
+ memoryStore:
+ enabled: true
+ maxSize: 250Mi
+ websocket:
+ port: 8080
+ enabled: true
+ natsBox:
+ enabled: false
+ service:
+ merge:
+ type: LoadBalancer
+ ports:
+ monitor:
+ enabled: true
+ container:
+ image:
+ tag: 2.10.7-alpine
+ pullPolicy: IfNotPresent
+ repository: nats
+ merge:
+ resources:
+ limits:
+ cpu: 100m
+ memory: 250Mi
+ requests:
+ cpu: 100m
+ memory: 250Mi
+ podTemplate:
+ merge:
+ spec:
+ tolerations:
+ - effect: NoSchedule
+ key: cloud.google.com/gke-spot
+ operator: Equal
+ value: 'true'
+ - effect: NoSchedule
+ key: kubernetes.azure.com/scalesetpriority
+ operator: Equal
+ value: spot
+ metadata:
+ annotations:
+ prometheus.io/port: '7777'
+ prometheus.io/scrape: 'true'
+ topologySpreadConstraints:
+ kubernetes.io/hostname:
+ maxSkew: 1
+ whenUnsatisfiable: DoNotSchedule
+ promExporter:
+ port: 7777
+ image:
+ tag: 0.13.0
+ pullPolicy: IfNotPresent
+ repository: natsio/prometheus-nats-exporter
+ enabled: true
+ extraResources: []
+ gatewayName: istio-system/tfy-wildcard
+ natsServerHost: ''
+ natsMetricsServerHost: ''
+clickhouse:
+ enabled: false
+ shardsCount: 2
+ replicasCount: 2
+ user: exampleUser
+ password: examplePassword
+ zookeeperHost: zookeeper-headless
+ zookeeperPort: '2181'
+ image: clickhouse/clickhouse-server:23.4.2
+ resources:
+ requests:
+ memory: 1024Mi
+ cpu: 500m
+ ephemeralStorage: 1024Mi
+ limits:
+ memory: 2048Mi
+ cpu: 1000m
+ ephemeralStorage: 2048Mi
+ storage:
+ storageClassName: ''
+ size: 10Gi
+ nats:
+ url: >-
+ http://{{ .Release.Name }}-nats.{{ .Release.Namespace
+ }}.svc.cluster.local:4222
+ subjects: tfy-model-logs.test
+ username: clickhouse-request-logs-reader
+ password:
diff --git a/charts/mlfoundry-server/Chart.yaml b/charts/mlfoundry-server/Chart.yaml
new file mode 100644
index 00000000..a3405b4c
--- /dev/null
+++ b/charts/mlfoundry-server/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: mlfoundry-server
+version: 0.2.103-rc.7
+description: "Helm Chart for MLFoundry"
+maintainers:
+ - name: truefoundry
diff --git a/charts/mlfoundry-server/templates/_helpers.tpl b/charts/mlfoundry-server/templates/_helpers.tpl
new file mode 100644
index 00000000..4c214159
--- /dev/null
+++ b/charts/mlfoundry-server/templates/_helpers.tpl
@@ -0,0 +1,101 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create a default fully qualified app name.
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+ If release name contains chart name it will be used as a full name.
+ */}}
+{{- define "app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Create chart name and version as used by the chart label.
+ */}}
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Common labels
+ */}}
+{{- define "app.labels" -}}
+helm.sh/chart: {{ include "app.chart" . }}
+{{- range $name, $value := .Values.commonLabels }}
+{{ $name }}: {{ tpl $value $ | quote }}
+{{- end }}
+{{ include "app.selectorLabels" . }}
+{{- if .Values.imageTag }}
+app.kubernetes.io/version: {{ .Values.imageTag | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+ Selector labels
+ */}}
+{{- define "app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+ Create the name of the service account to use
+ */}}
+{{- define "app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+
+{{/*
+ Parse env from template
+ */}}
+{{- define "app.parseEnv" -}}
+{{ tpl (.Values.env | toYaml) . }}
+{{- end }}
+
+{{/*
+ Create the env file
+ */}}
+{{- define "app.env" }}
+{{- range $key, $val := (include "app.parseEnv" .) | fromYaml }}
+{{- if and $val (contains "${k8s-secret" ($val | toString)) }}
+{{- if eq (regexSplit "/" $val -1 | len) 2 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ $.Values.envSecretName }}
+ key: {{ index (regexSplit "/" $val -1) 1 | trimSuffix "}" }}
+{{- else if eq (regexSplit "/" $val -1 | len) 3 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ index (regexSplit "/" $val -1) 1 }}
+ key: {{ index (regexSplit "/" $val -1) 2 | trimSuffix "}" }}
+{{- else }}
+{{- fail "Invalid secret supplied" }}
+{{- end }}
+{{- else }}
+- name: {{ $key }}
+ value: {{ $val | quote }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/mlfoundry-server/templates/deployment.yaml b/charts/mlfoundry-server/templates/deployment.yaml
new file mode 100644
index 00000000..67a525b5
--- /dev/null
+++ b/charts/mlfoundry-server/templates/deployment.yaml
@@ -0,0 +1,63 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "app.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "app.labels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "app.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ env:
+ {{- include "app.env" . | trim | nindent 12 }}
+ image: "{{ .Values.imageRepository }}:{{ .Values.imageTag }}"
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.service.port }}
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- if .Values.healthcheck.enabled }}
+ livenessProbe:
+ {{- .Values.healthcheck.livenessProbe | toYaml | nindent 12 }}
+ readinessProbe:
+ {{- .Values.healthcheck.readinessProbe | toYaml | nindent 12 }}
+ {{- end }}
+ volumeMounts:
+ {{- toYaml .Values.extraVolumeMounts | nindent 12 }}
+ volumes:
+ {{- toYaml .Values.extraVolumes | nindent 8 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.topologySpreadConstraints }}
+ topologySpreadConstraints:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
\ No newline at end of file
diff --git a/charts/mlfoundry-server/templates/ingress.yaml b/charts/mlfoundry-server/templates/ingress.yaml
new file mode 100644
index 00000000..1fe0c59d
--- /dev/null
+++ b/charts/mlfoundry-server/templates/ingress.yaml
@@ -0,0 +1,39 @@
+{{- if .Values.ingress.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+{{- if .Values.ingress.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.ingress.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- end }}
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.ingress.labels }}
+ {{- toYaml .Values.ingress.labels | nindent 4 }}
+ {{- end }}
+spec:
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+ rules:
+ {{- range $host := .Values.ingress.hosts }}
+ - host: {{ $host }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ $serviceName }}
+ port:
+ number: {{ $servicePort }}
+
+ {{- end -}}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- toYaml .Values.ingress.tls | nindent 4 }}
+ {{- end -}}
+{{- end -}}
diff --git a/charts/mlfoundry-server/templates/service.yaml b/charts/mlfoundry-server/templates/service.yaml
new file mode 100644
index 00000000..a45d8822
--- /dev/null
+++ b/charts/mlfoundry-server/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: {{ .Values.service.port }}
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "app.selectorLabels" . | nindent 4 }}
\ No newline at end of file
diff --git a/charts/mlfoundry-server/templates/serviceaccount.yaml b/charts/mlfoundry-server/templates/serviceaccount.yaml
new file mode 100644
index 00000000..a41b8ac6
--- /dev/null
+++ b/charts/mlfoundry-server/templates/serviceaccount.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "app.serviceAccountName" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations:
+{{ tpl (toYaml . | indent 4) $ }}
+{{- end }}
+imagePullSecrets:
+{{- if .Values.global.existingTruefoundryImagePullSecretName }}
+ - name: {{ .Values.global.existingTruefoundryImagePullSecretName }}
+{{- else }}
+ - name: truefoundry-image-pull-secret
+{{- end }}
+{{- end }}
diff --git a/charts/mlfoundry-server/templates/virtualservice.yaml b/charts/mlfoundry-server/templates/virtualservice.yaml
new file mode 100644
index 00000000..b220274c
--- /dev/null
+++ b/charts/mlfoundry-server/templates/virtualservice.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.istio.virtualservice.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.istio.io/v1beta1
+kind: VirtualService
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.istio.virtualservice.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.istio.virtualservice.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ namespace: {{ .Release.Namespace }}
+spec:
+ gateways:
+ {{- range .Values.istio.virtualservice.gateways}}
+ - {{ . }}
+ {{- end }}
+ hosts:
+ {{- range .Values.istio.virtualservice.hosts}}
+ - {{ . }}
+ {{- end }}
+ http:
+ - route:
+ - destination:
+ host: {{ include "app.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+ port:
+ number: {{ .Values.service.port }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/mlfoundry-server/values.yaml b/charts/mlfoundry-server/values.yaml
new file mode 100644
index 00000000..b95eb251
--- /dev/null
+++ b/charts/mlfoundry-server/values.yaml
@@ -0,0 +1,89 @@
+global: {}
+imageRepository: truefoundrycloud/mlfoundry-server
+replicaCount: 1
+environmentName: default
+envSecretName: mlfoundry-server-env-secret
+imagePullPolicy: IfNotPresent
+nameOverride: ''
+fullnameOverride: ''
+podAnnotations: {}
+podSecurityContext: {}
+commonLabels: {}
+securityContext: {}
+healthcheck:
+ enabled: true
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /
+ port: 5000
+ scheme: HTTP
+ initialDelaySeconds: 90
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+ livenessProbe:
+ failureThreshold: 3
+ httpGet:
+ path: /
+ port: 5000
+ scheme: HTTP
+ initialDelaySeconds: 90
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 1
+resources:
+ limits:
+ cpu: 400m
+ memory: 2048Mi
+ ephemeral-storage: 256Mi
+ requests:
+ cpu: 200m
+ memory: 1024Mi
+ ephemeral-storage: 128Mi
+nodeSelector: {}
+tolerations: {}
+affinity: {}
+topologySpreadConstraints: {}
+ingress:
+ enabled: false
+ annotations: {}
+ labels: {}
+ ingressClassName: istio
+ tls: []
+ hosts: []
+istio:
+ virtualservice:
+ enabled: false
+ annotations: {}
+ gateways: []
+ hosts: []
+service:
+ type: ClusterIP
+ port: 5000
+ annotations: {}
+serviceAccount:
+ create: true
+ name: mlfoundry-server
+ annotations: {}
+imageTag: 1ae31419e11b6f9381ce14e6199fd0f4ed59419b
+extraVolumes: []
+extraVolumeMounts: []
+env:
+ DB_NAME: ${k8s-secret/truefoundry-creds/DB_NAME}
+ DB_USERNAME: ${k8s-secret/truefoundry-creds/DB_USERNAME}
+ DB_PASSWORD: ${k8s-secret/truefoundry-creds/DB_PASSWORD}
+ DB_HOST: ${k8s-secret/truefoundry-creds/DB_HOST}
+ DB_POSTGRES_SCHEMA: mlfoundry
+ DB_PORT: '5432'
+ DB_DIALECT: postgresql+psycopg2
+ AUTH_SERVER_URL: https://auth.truefoundry.com
+ ARTIFACT_ROOT: s3://{{ .Values.env.S3_BUCKET_NAME }}
+ MLFLOW_S3_ENDPOINT_URL: '{{ .Values.env.S3_ENDPOINT_URL }}'
+ prometheus_multiproc_dir: .prom_metrics
+ MULTITENANT: 'false'
+ TENANT_NAME: '{{ .Values.global.tenantName }}'
+ SVC_FOUNDRY_SERVICE_API_KEY: ${k8s-secret/truefoundry-creds/TFY_API_KEY}
+ SERVICEFOUNDRY_SERVER_URL: >-
+ http://{{ .Release.Name }}-servicefoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:3000
diff --git a/charts/servicefoundry-server/Chart.yaml b/charts/servicefoundry-server/Chart.yaml
new file mode 100644
index 00000000..0d69e001
--- /dev/null
+++ b/charts/servicefoundry-server/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: servicefoundry-server
+version: 0.3.140-rc.13
+description: "Servicefoundry-server deployment chart"
+maintainers:
+ - name: truefoundry
diff --git a/charts/servicefoundry-server/templates/_helpers.tpl b/charts/servicefoundry-server/templates/_helpers.tpl
new file mode 100644
index 00000000..9572fb55
--- /dev/null
+++ b/charts/servicefoundry-server/templates/_helpers.tpl
@@ -0,0 +1,132 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create a default fully qualified app name.
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+ If release name contains chart name it will be used as a full name.
+ */}}
+{{- define "app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Create chart name and version as used by the chart label.
+ */}}
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Common labels
+ */}}
+{{- define "app.labels" -}}
+helm.sh/chart: {{ include "app.chart" . }}
+{{- range $name, $value := .Values.commonLabels }}
+{{ $name }}: {{ tpl $value $ | quote }}
+{{- end }}
+{{ include "app.selectorLabels" . }}
+{{- if .Values.imageTag }}
+app.kubernetes.io/version: {{ .Values.imageTag | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+ Selector labels
+ */}}
+{{- define "app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+ Create the name of the service account to use
+ */}}
+{{- define "app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Parse env from template
+ */}}
+{{- define "app.parseEnv" -}}
+{{ tpl (.Values.env | toYaml) . }}
+
+{{- end }}
+
+{{/*
+ Create the env file
+ */}}
+{{- define "app.env" }}
+{{- range $key, $val := (include "app.parseEnv" .) | fromYaml }}
+{{- if and $val (contains "${k8s-secret" ($val | toString)) }}
+{{- if eq (regexSplit "/" $val -1 | len) 2 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ $.Values.envSecretName }}
+ key: {{ index (regexSplit "/" $val -1) 1 | trimSuffix "}" }}
+{{- else if eq (regexSplit "/" $val -1 | len) 3 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ index (regexSplit "/" $val -1) 1 }}
+ key: {{ index (regexSplit "/" $val -1) 2 | trimSuffix "}" }}
+{{- else }}
+{{- fail "Invalid secret supplied" }}
+{{- end }}
+{{- else }}
+- name: {{ $key }}
+ value: {{ $val | quote }}
+{{- end }}
+{{- end }}
+{{- if (tpl .Values.configs.cicdTemplates .) }}
+- name: CICD_TEMPLATES_DIRECTORY
+ value: /opt/truefoundry/configs/cicd-templates
+{{- end }}
+{{- end }}
+
+{{- define "app.volumes" -}}
+{{- $volumes := list -}}
+{{- if .Values.extraVolumes }}
+ {{- range .Values.extraVolumes }}
+ {{- $volumes = append $volumes . }}
+ {{- end }}
+{{- end }}
+{{- if (tpl .Values.configs.cicdTemplates .) }}
+ {{- $volumes = append $volumes (dict "name" "configs-cicd-templates" "configMap" (dict "name" (tpl .Values.configs.cicdTemplates .))) }}
+{{- end }}
+{{- $volumes | toYaml -}}
+{{- end -}}
+
+
+{{- define "app.volumeMounts" -}}
+{{- $volumeMounts := list -}}
+{{- if .Values.extraVolumeMounts }}
+ {{- range .Values.extraVolumeMounts }}
+ {{- $volumeMounts = append $volumeMounts . }}
+ {{- end }}
+{{- end }}
+{{- if (tpl .Values.configs.cicdTemplates .) }}
+ {{- $volumeMounts = append $volumeMounts (dict "name" "configs-cicd-templates" "mountPath" "/opt/truefoundry/configs/cicd-templates") }}
+{{- end }}
+{{- $volumeMounts | toYaml -}}
+{{- end -}}
diff --git a/charts/servicefoundry-server/templates/clusterrolebinding.yaml b/charts/servicefoundry-server/templates/clusterrolebinding.yaml
new file mode 100644
index 00000000..8523cb17
--- /dev/null
+++ b/charts/servicefoundry-server/templates/clusterrolebinding.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.rbac.enabled -}}
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: {{ include "app.serviceAccountName" . }}-admin-rbac
+subjects:
+ - kind: ServiceAccount
+ name: {{ include "app.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+roleRef:
+ kind: ClusterRole
+ name: cluster-admin
+ apiGroup: rbac.authorization.k8s.io
+{{- end }}
diff --git a/charts/servicefoundry-server/templates/deployment.yaml b/charts/servicefoundry-server/templates/deployment.yaml
new file mode 100644
index 00000000..8cd45e21
--- /dev/null
+++ b/charts/servicefoundry-server/templates/deployment.yaml
@@ -0,0 +1,67 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "app.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "app.labels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "app.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ env:
+ {{- include "app.env" . | trim | nindent 12 }}
+ image: "{{ .Values.imageRepository }}:{{ .Values.imageTag }}"
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.service.port }}
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- if .Values.healthcheck.enabled }}
+ livenessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.liveness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ readinessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.readiness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ {{- end }}
+ volumeMounts:
+ {{- include "app.volumeMounts" . | nindent 12 }}
+ volumes:
+ {{- include "app.volumes" . | nindent 8 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.topologySpreadConstraints }}
+ topologySpreadConstraints:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/charts/servicefoundry-server/templates/ingress.yaml b/charts/servicefoundry-server/templates/ingress.yaml
new file mode 100644
index 00000000..1fe0c59d
--- /dev/null
+++ b/charts/servicefoundry-server/templates/ingress.yaml
@@ -0,0 +1,39 @@
+{{- if .Values.ingress.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+{{- if .Values.ingress.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.ingress.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- end }}
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.ingress.labels }}
+ {{- toYaml .Values.ingress.labels | nindent 4 }}
+ {{- end }}
+spec:
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+ rules:
+ {{- range $host := .Values.ingress.hosts }}
+ - host: {{ $host }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ $serviceName }}
+ port:
+ number: {{ $servicePort }}
+
+ {{- end -}}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- toYaml .Values.ingress.tls | nindent 4 }}
+ {{- end -}}
+{{- end -}}
diff --git a/charts/servicefoundry-server/templates/service.yaml b/charts/servicefoundry-server/templates/service.yaml
new file mode 100644
index 00000000..a45d8822
--- /dev/null
+++ b/charts/servicefoundry-server/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: {{ .Values.service.port }}
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "app.selectorLabels" . | nindent 4 }}
\ No newline at end of file
diff --git a/charts/servicefoundry-server/templates/serviceaccount.yaml b/charts/servicefoundry-server/templates/serviceaccount.yaml
new file mode 100644
index 00000000..a41b8ac6
--- /dev/null
+++ b/charts/servicefoundry-server/templates/serviceaccount.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "app.serviceAccountName" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations:
+{{ tpl (toYaml . | indent 4) $ }}
+{{- end }}
+imagePullSecrets:
+{{- if .Values.global.existingTruefoundryImagePullSecretName }}
+ - name: {{ .Values.global.existingTruefoundryImagePullSecretName }}
+{{- else }}
+ - name: truefoundry-image-pull-secret
+{{- end }}
+{{- end }}
diff --git a/charts/servicefoundry-server/templates/virtualservice.yaml b/charts/servicefoundry-server/templates/virtualservice.yaml
new file mode 100644
index 00000000..b220274c
--- /dev/null
+++ b/charts/servicefoundry-server/templates/virtualservice.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.istio.virtualservice.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.istio.io/v1beta1
+kind: VirtualService
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.istio.virtualservice.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.istio.virtualservice.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ namespace: {{ .Release.Namespace }}
+spec:
+ gateways:
+ {{- range .Values.istio.virtualservice.gateways}}
+ - {{ . }}
+ {{- end }}
+ hosts:
+ {{- range .Values.istio.virtualservice.hosts}}
+ - {{ . }}
+ {{- end }}
+ http:
+ - route:
+ - destination:
+ host: {{ include "app.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+ port:
+ number: {{ .Values.service.port }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/servicefoundry-server/values.yaml b/charts/servicefoundry-server/values.yaml
new file mode 100644
index 00000000..c62001cd
--- /dev/null
+++ b/charts/servicefoundry-server/values.yaml
@@ -0,0 +1,146 @@
+global: {}
+imageRepository: truefoundrycloud/servicefoundry-server
+replicaCount: 1
+environmentName: default
+envSecretName: servicefoundry-server-env-secret
+imagePullPolicy: IfNotPresent
+nameOverride: ''
+fullnameOverride: ''
+podAnnotations: {}
+podSecurityContext: {}
+commonLabels: {}
+securityContext: {}
+healthcheck:
+ enabled: true
+ readiness:
+ port: 3000
+ path: /
+ liveness:
+ port: 3000
+ path: /
+resources:
+ limits:
+ cpu: 400m
+ memory: 512Mi
+ ephemeral-storage: 256Mi
+ requests:
+ cpu: 200m
+ memory: 256Mi
+ ephemeral-storage: 128Mi
+nodeSelector: {}
+tolerations: {}
+affinity: {}
+topologySpreadConstraints: {}
+ingress:
+ enabled: false
+ annotations: {}
+ labels: {}
+ ingressClassName: istio
+ tls: []
+ hosts: []
+istio:
+ virtualservice:
+ enabled: false
+ annotations: {}
+ gateways: []
+ hosts: []
+service:
+ type: ClusterIP
+ port: 3000
+ annotations: {}
+serviceAccount:
+ create: true
+ name: servicefoundry-server
+ annotations: {}
+extraVolumes: []
+extraVolumeMounts: []
+rbac:
+ enabled: true
+env:
+ LOG_LEVEL: info
+ S3_BUCKET_NAME: ''
+ GS_BUCKET_NAME: ''
+ AZURE_BLOB_URI: ''
+ AZURE_BLOB_CONNECTION_STRING: ''
+ DB_NAME: ${k8s-secret/truefoundry-creds/DB_NAME}
+ DB_USERNAME: ${k8s-secret/truefoundry-creds/DB_USERNAME}
+ DB_PASSWORD: ${k8s-secret/truefoundry-creds/DB_PASSWORD}
+ DB_HOST: ${k8s-secret/truefoundry-creds/DB_HOST}
+ DB_PORT: '5432'
+ STRIPE_KEY: ''
+ STRIPE_WEBHOOK_SECRET: ''
+ SVC_FOUNDRY_SERVICE_API_KEY: ${k8s-secret/truefoundry-creds/TFY_API_KEY}
+ PORT: '3000'
+ SWAGGER_ENABLE: '0'
+ NODE_ENV: production
+ GITHUB_PRIVATE_KEY: ''
+ GITHUB_APP_ID: ''
+ GITHUB_PAT: ''
+ BITBUCKET_CLIENT_ID: ''
+ BITBUCKET_CLIENT_SECRET: ''
+ GITHUB_INSTALLATION_URL: ''
+ GITLAB_APP_ID: ''
+ GITLAB_APP_SECRET: ''
+ GITLAB_SCOPE: ''
+ CONTROL_PLANE_URL: '{{ .Values.global.controlPlaneURL }}'
+ TFY_BUILD_LOGS_URL: '{{ .Values.global.controlPlaneURL }}/api/svc'
+ TFY_BUILD_WS_URL: '{{ .Values.global.controlPlaneURL }}'
+ TFY_BUILD_WS_PATH: /api/svc/socket.io
+ LOKI_URL: http://loki.loki.svc.cluster.local:3100
+ AUTH_SERVER_URL: https://auth.truefoundry.com
+ ISTIO_INJECTION_STATE: disabled
+ WORKSPACE_PER_USER_WITHOUT_PAYMENT: '-1'
+ TENANT_NAME: '{{ .Values.global.tenantName }}'
+ MULTITENANT: 'false'
+ MANIFEST_SERVICE_URL: >-
+ http://{{ .Release.Name }}-sfy-manifest-service.{{ .Release.Namespace
+ }}.svc.cluster.local:8080
+ MLFOUNDRY_SERVER_URL: >-
+ http://{{ .Release.Name }}-mlfoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:5000
+ DEFAULT_CLOUD_PROVIDER: aws
+ MIN_CLI_VERSION: 0.10.9
+ OTEL_SERVICE_NAME: sfy-server
+ NATS_CONTROLPLANE_ACCOUNT_SEED: ${k8s-secret/truefoundry-nats-secret/NATS_CONTROLPLANE_ACCOUNT_SEED}
+ NATS_URL: >-
+ http://{{ .Release.Name }}-nats.{{ .Release.Namespace
+ }}.svc.cluster.local:4222
+ SECRET_STORE: aws-ssm
+ CLUSTER_PROXY_URL: >-
+ http://{{ .Release.Name }}-tfy-controller.{{ .Release.Namespace
+ }}.svc.cluster.local:8123
+ ENABLE_SERVER_SIDE_APPLY: 'true'
+ LLM_GATEWAY_URL: ''
+ TRUEFOUNDRY_PUBLIC_ENABLED: ''
+ LLM_GATEWAY_CATALOGUE_BASE_URL: https://catalogue.truefoundry.com/llm-gateway/devtest
+ MAX_REQUEST_SIZE: ''
+ METRICS_MAX_DATA_POINTS: '60'
+ PROMETHEUS_SCRAP_INTERVAL_SECONDS: '15'
+ CONTROL_PLANE_PROMETHEUS_URL: http://prometheus-operated.prometheus.svc.cluster.local:9090/
+ MODEL_CATALOGUE_BASE_URL: https://catalogue.truefoundry.com/models
+ APPLICATION_CATALOGUE_BASE_URL: https://catalogue.truefoundry.com/templates
+ CLICKHOUSE_HOST: ''
+ CLICKHOUSE_USER: ''
+ CLICKHOUSE_PASSWORD: ''
+ CLICKHOUSE_WAIT_TIMEOUT: 5m
+ HELM_CHART_EXPORT_DEPENDENCY_LIMIT: '100'
+ SLACK_ALERT_URL: ''
+ SLACK_BILLING_ALERT_URL: ''
+ DB_CONNECTION_POOL_MAX_COUNT: '10'
+ VCS_INTEGRATION_STATE_OBJECT_HASH_SECRET: ''
+ BUILD_NAMESPACE: truefoundry
+ KUBE_CONTEXT: ''
+ BUILDKIT_SERVICE_URL: >-
+ {{ .Release.Name }}-tfy-buildkitd-service.{{ .Release.Namespace
+ }}.svc.cluster.local:1234
+ ACCESS_TFY_GATEWAY_MODELS_TENANT_DENY_LIST: ''
+ MIGRATION_SERVER_URL: https://migration-server.truefoundry.com
+ AUTOPILOT_ENABLED: 'false'
+ AUTOPILOT_CONSUMER_BATCH_MAX_MESSAGES: '50'
+ AUTOPILOT_CONSUMER_MESSAGE_EXPIRY_MS: '10000'
+ BUILD_CALLBACK_URL: >-
+ http://{{ .Release.Name }}-servicefoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:3000
+configs:
+ cicdTemplates: '{{ .Release.Name }}-cicd-templates-cm'
+imageTag: bbeae9d8976c73fcac4af7351839b1ef9937237d
diff --git a/charts/sfy-manifest-service/Chart.yaml b/charts/sfy-manifest-service/Chart.yaml
new file mode 100644
index 00000000..29f8825a
--- /dev/null
+++ b/charts/sfy-manifest-service/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: sfy-manifest-service
+version: 0.1.119-rc.5
+description: "Sfy manifest service deployment chart"
+maintainers:
+ - name: truefoundry
diff --git a/charts/sfy-manifest-service/templates/_helpers.tpl b/charts/sfy-manifest-service/templates/_helpers.tpl
new file mode 100644
index 00000000..7da990d1
--- /dev/null
+++ b/charts/sfy-manifest-service/templates/_helpers.tpl
@@ -0,0 +1,100 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create a default fully qualified app name.
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+ If release name contains chart name it will be used as a full name.
+ */}}
+{{- define "app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Create chart name and version as used by the chart label.
+ */}}
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Common labels
+ */}}
+{{- define "app.labels" -}}
+helm.sh/chart: {{ include "app.chart" . }}
+{{- range $name, $value := .Values.commonLabels }}
+{{ $name }}: {{ tpl $value $ | quote }}
+{{- end }}
+{{ include "app.selectorLabels" . }}
+{{- if .Values.imageTag }}
+app.kubernetes.io/version: {{ .Values.imageTag | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+ Selector labels
+ */}}
+{{- define "app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+ Create the name of the service account to use
+ */}}
+{{- define "app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Parse env from template
+ */}}
+{{- define "app.parseEnv" -}}
+{{ tpl (.Values.env | toYaml) . }}
+{{- end }}
+
+{{/*
+ Create the env file
+ */}}
+{{- define "app.env" }}
+{{- range $key, $val := (include "app.parseEnv" .) | fromYaml }}
+{{- if and $val (contains "${k8s-secret" ($val | toString)) }}
+{{- if eq (regexSplit "/" $val -1 | len) 2 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ $.Values.envSecretName }}
+ key: {{ index (regexSplit "/" $val -1) 1 | trimSuffix "}" }}
+{{- else if eq (regexSplit "/" $val -1 | len) 3 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ index (regexSplit "/" $val -1) 1 }}
+ key: {{ index (regexSplit "/" $val -1) 2 | trimSuffix "}" }}
+{{- else }}
+{{- fail "Invalid secret supplied" }}
+{{- end }}
+{{- else }}
+- name: {{ $key }}
+ value: {{ $val | quote }}
+{{- end }}
+{{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/sfy-manifest-service/templates/deployment.yaml b/charts/sfy-manifest-service/templates/deployment.yaml
new file mode 100644
index 00000000..49f07d11
--- /dev/null
+++ b/charts/sfy-manifest-service/templates/deployment.yaml
@@ -0,0 +1,67 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "app.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "app.labels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "app.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ env:
+ {{- include "app.env" . | trim | nindent 12 }}
+ image: "{{ .Values.imageRepository }}:{{ .Values.imageTag }}"
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.service.port }}
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- if .Values.healthcheck.enabled }}
+ livenessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.liveness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ readinessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.readiness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ {{- end }}
+ volumeMounts:
+ {{- toYaml .Values.extraVolumeMounts | nindent 12 }}
+ volumes:
+ {{- toYaml .Values.extraVolumes | nindent 8 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.topologySpreadConstraints }}
+ topologySpreadConstraints:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/charts/sfy-manifest-service/templates/ingress.yaml b/charts/sfy-manifest-service/templates/ingress.yaml
new file mode 100644
index 00000000..1fe0c59d
--- /dev/null
+++ b/charts/sfy-manifest-service/templates/ingress.yaml
@@ -0,0 +1,39 @@
+{{- if .Values.ingress.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+{{- if .Values.ingress.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.ingress.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- end }}
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.ingress.labels }}
+ {{- toYaml .Values.ingress.labels | nindent 4 }}
+ {{- end }}
+spec:
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+ rules:
+ {{- range $host := .Values.ingress.hosts }}
+ - host: {{ $host }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ $serviceName }}
+ port:
+ number: {{ $servicePort }}
+
+ {{- end -}}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- toYaml .Values.ingress.tls | nindent 4 }}
+ {{- end -}}
+{{- end -}}
diff --git a/charts/sfy-manifest-service/templates/service.yaml b/charts/sfy-manifest-service/templates/service.yaml
new file mode 100644
index 00000000..d1527128
--- /dev/null
+++ b/charts/sfy-manifest-service/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: {{ .Values.service.port }}
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "app.selectorLabels" . | nindent 4 }}
diff --git a/charts/sfy-manifest-service/templates/serviceaccount.yaml b/charts/sfy-manifest-service/templates/serviceaccount.yaml
new file mode 100644
index 00000000..a41b8ac6
--- /dev/null
+++ b/charts/sfy-manifest-service/templates/serviceaccount.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "app.serviceAccountName" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations:
+{{ tpl (toYaml . | indent 4) $ }}
+{{- end }}
+imagePullSecrets:
+{{- if .Values.global.existingTruefoundryImagePullSecretName }}
+ - name: {{ .Values.global.existingTruefoundryImagePullSecretName }}
+{{- else }}
+ - name: truefoundry-image-pull-secret
+{{- end }}
+{{- end }}
diff --git a/charts/sfy-manifest-service/templates/virtualservice.yaml b/charts/sfy-manifest-service/templates/virtualservice.yaml
new file mode 100644
index 00000000..b220274c
--- /dev/null
+++ b/charts/sfy-manifest-service/templates/virtualservice.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.istio.virtualservice.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.istio.io/v1beta1
+kind: VirtualService
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.istio.virtualservice.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.istio.virtualservice.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ namespace: {{ .Release.Namespace }}
+spec:
+ gateways:
+ {{- range .Values.istio.virtualservice.gateways}}
+ - {{ . }}
+ {{- end }}
+ hosts:
+ {{- range .Values.istio.virtualservice.hosts}}
+ - {{ . }}
+ {{- end }}
+ http:
+ - route:
+ - destination:
+ host: {{ include "app.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+ port:
+ number: {{ .Values.service.port }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/sfy-manifest-service/values.yaml b/charts/sfy-manifest-service/values.yaml
new file mode 100644
index 00000000..0d0809b3
--- /dev/null
+++ b/charts/sfy-manifest-service/values.yaml
@@ -0,0 +1,83 @@
+global: {}
+imageRepository: truefoundrycloud/sfy-manifest-service
+replicaCount: 1
+environmentName: default
+envSecretName: sfy-manifest-service-env-secret
+imagePullPolicy: IfNotPresent
+nameOverride: ''
+fullnameOverride: ''
+podAnnotations: {}
+podSecurityContext: {}
+commonLabels: {}
+securityContext: {}
+healthcheck:
+ enabled: true
+ readiness:
+ port: 8080
+ path: /healthy
+ liveness:
+ port: 8080
+ path: /healthy
+resources:
+ limits:
+ cpu: 200m
+ memory: 256Mi
+ ephemeral-storage: 256Mi
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ ephemeral-storage: 128Mi
+nodeSelector: {}
+tolerations: {}
+affinity: {}
+topologySpreadConstraints: {}
+ingress:
+ enabled: false
+ annotations: {}
+ labels: {}
+ ingressClassName: istio
+ tls: []
+ hosts: []
+istio:
+ virtualservice:
+ enabled: false
+ annotations: {}
+ gateways: []
+ hosts: []
+service:
+ type: ClusterIP
+ port: 8080
+ annotations: {}
+serviceAccount:
+ create: true
+ name: sfy-manifest-service
+ annotations: {}
+extraVolumes: []
+extraVolumeMounts: []
+env:
+ GIN_MODE: release
+ PORT: '8080'
+ SFY_SERVER_URL: >-
+ http://{{ .Release.Name }}-servicefoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:3000
+ MLF_SERVER_URL: >-
+ http://{{ .Release.Name }}-mlfoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:5000
+ SFY_API_KEY: ${k8s-secret/truefoundry-creds/TFY_API_KEY}
+ PROCESS_TICKER_PERIOD_SECONDS: '5'
+ TENANT_NAME: '{{ .Values.global.tenantName }}'
+ AUTH_SERVER_URL: https://auth.truefoundry.com
+ HELM_SIZE_LIMIT_BYTES: '307200'
+ ASYNC_PROCESSOR_SIDECAR_IMAGE: >-
+ public.ecr.aws/w0y0d8g6/truefoundrycloud/async_processor:35b639ea3db5490f816379de0c92a9a933338cdf
+ TFY_MODEL_DOWNLOADER_IMAGE: public.ecr.aws/truefoundrycloud/tfy-model-downloader:0.1.4
+ APP_CATALOGUE_ENDPOINT: https://catalogue.truefoundry.com/templates/
+ AUTOPILOT_PROCESSOR_ENABLED: 'false'
+ AUTOPILOT_PROCESSOR_NATS_URL: >-
+ nats://{{ .Release.Name }}-nats.{{ .Release.Namespace
+ }}.svc.cluster.local:4222
+ AUTOPILOT_PROCESSOR_NATS_PULL_MAX_BYTES: '10485760'
+ AUTOPILOT_PROCESSOR_NATS_ACK_WAIT: '120'
+ AUTOPILOT_PROCESSOR_PUBLISH_ASYNC_MAX_PENDING: '100'
+ AUTOPILOT_PROCESSOR_NUMBER_OF_WORKERS: '2'
+imageTag: 30a27bc05c9df4485882df2ae773a4f34f134a19
diff --git a/charts/tfy-build/Chart.yaml b/charts/tfy-build/Chart.yaml
new file mode 100644
index 00000000..aaa179b0
--- /dev/null
+++ b/charts/tfy-build/Chart.yaml
@@ -0,0 +1,11 @@
+apiVersion: v2
+name: tfy-build
+version: 0.4.3
+description: "TFY Build chart"
+maintainers:
+ - name: truefoundry
+dependencies:
+ - condition: tfy-buildkitd-service.enabled
+ name: tfy-buildkitd-service
+ repository: https://truefoundry.github.io/infra-charts/
+ version: 0.1.3
diff --git a/charts/tfy-build/templates/_helpers.tpl b/charts/tfy-build/templates/_helpers.tpl
new file mode 100644
index 00000000..2c618d26
--- /dev/null
+++ b/charts/tfy-build/templates/_helpers.tpl
@@ -0,0 +1,42 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create a default fully qualified app name.
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+ If release name contains chart name it will be used as a full name.
+ */}}
+{{- define "app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Create chart name and version as used by the chart label.
+ */}}
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create the name of the service account to use
+ */}}
+{{- define "app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/charts/tfy-build/templates/build-workflow.yaml b/charts/tfy-build/templates/build-workflow.yaml
new file mode 100644
index 00000000..89ccfa4d
--- /dev/null
+++ b/charts/tfy-build/templates/build-workflow.yaml
@@ -0,0 +1,611 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "app.serviceAccountName" . }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations:
+{{ tpl (toYaml . | indent 4) $ }}
+{{- end }}
+imagePullSecrets:
+{{- if .Values.global.existingTruefoundryImagePullSecretName }}
+ - name: {{ .Values.global.existingTruefoundryImagePullSecretName }}
+{{- else }}
+ - name: truefoundry-image-pull-secret
+{{- end }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: {{ include "app.serviceAccountName" . }}-role
+rules:
+ - apiGroups:
+ - argoproj.io
+ resources:
+ - workflowtaskresults
+ verbs:
+ - create
+ - patch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: {{ include "app.serviceAccountName" . }}-role-binding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: {{ include "app.serviceAccountName" . }}-role
+subjects:
+ - kind: ServiceAccount
+ namespace: {{ .Release.Namespace }}
+ name: {{ include "app.serviceAccountName" . }}
+---
+apiVersion: argoproj.io/v1alpha1
+kind: WorkflowTemplate
+metadata:
+ name: build
+spec:
+ serviceAccountName: {{ include "app.serviceAccountName" . }}
+ workflowMetadata:
+ labelsFrom:
+ "truefoundry.com/buildName":
+ expression: workflow.name
+ entrypoint: build
+ onExit: exit-handler
+ arguments:
+ parameters:
+ - name: callbackURL
+ - name: buildSource
+ - name: buildConfig
+ - name: dockerRegistryURL
+ - name: dockerRegistryUsername
+ - name: dockerRegistryPassword
+ - name: dockerRepo
+ - name: dockerTag
+ - name: buildkitServiceURL
+ templates:
+ - name: build
+ inputs:
+ parameters:
+ - name: buildSource
+ - name: buildConfig
+ - name: dockerRegistryURL
+ - name: dockerRegistryUsername
+ - name: dockerRegistryPassword
+ - name: dockerRepo
+ - name: dockerTag
+ - name: buildkitServiceURL
+ steps:
+ - - name: build-and-push
+ template: build-and-push
+ arguments:
+ parameters:
+ - name: buildSource
+ value: "{{`{{inputs.parameters.buildSource}}`}}"
+ - name: buildConfig
+ value: "{{`{{inputs.parameters.buildConfig}}`}}"
+ - name: dockerRegistryURL
+ value: "{{`{{inputs.parameters.dockerRegistryURL}}`}}"
+ - name: dockerRegistryUsername
+ value: "{{`{{inputs.parameters.dockerRegistryUsername}}`}}"
+ - name: dockerRegistryPassword
+ value: "{{`{{inputs.parameters.dockerRegistryPassword}}`}}"
+ - name: dockerRepo
+ value: "{{`{{inputs.parameters.dockerRepo}}`}}"
+ - name: dockerTag
+ value: "{{`{{inputs.parameters.dockerTag}}`}}"
+ - name: buildkitServiceURL
+ value: "{{`{{inputs.parameters.buildkitServiceURL}}`}}"
+ - name: build-and-push
+ metadata:
+ annotations:
+ cluster-autoscaler.kubernetes.io/safe-to-evict: 'false'
+ karpenter.sh/do-not-disrupt: 'true'
+ karpenter.sh/do-not-evict: 'true'
+ retryStrategy:
+ limit: 5
+ retryPolicy: "Always"
+ backoff:
+ duration: "30"
+ factor: 2
+ maxDuration: "1h"
+ inputs:
+ parameters:
+ - name: buildSource
+ - name: buildConfig
+ - name: dockerRegistryURL
+ - name: dockerRegistryUsername
+ - name: dockerRegistryPassword
+ - name: dockerRepo
+ - name: dockerTag
+ - name: buildkitServiceURL
+ volumes:
+ - name: truefoundry-docker-config
+ secret:
+ items:
+ - key: .dockerconfigjson
+ path: base_config.json
+ secretName: truefoundry-image-pull-secret
+ {{- with .Values.truefoundryWorkflows.extraVolumes }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ script:
+ image: truefoundrycloud/sfy-builder:{{ .Values.truefoundryWorkflows.sfyBuilder.version }}
+ command: [bash]
+ workingDir: /mnt/vol
+ {{- with .Values.truefoundryWorkflows.extraEnvs }}
+ env:
+ {{- toYaml . | nindent 6 }}
+ {{- end }}
+ source: |
+ #!/bin/bash
+ set -e -o pipefail
+
+ mkdir -p /root/.docker/
+ cp /root/.truefoundry/.docker/base_config.json /root/.docker/config.json
+
+ BUILD_SOURCE='{{`{{inputs.parameters.buildSource}}`}}'
+ BUILD_TYPE=$(echo $BUILD_SOURCE | jq -r '.type')
+
+ rm -f -R ./source-code
+
+ if [[ $BUILD_TYPE == "remote" ]]; then
+ REMOTE_URL=$(echo $BUILD_SOURCE | jq -r '.remote_uri')
+ printf "\033[36m[Start]\033[0m Downloading source code from remote source\n"
+ mkdir -p source-code
+ curl -s -o project-files.tar.gz $REMOTE_URL
+ tar -xf project-files.tar.gz -C source-code
+ cd source-code
+ elif [[ $BUILD_TYPE == "git" || $BUILD_TYPE == "github" ]]; then
+ GIT_URL=$(echo $BUILD_SOURCE | jq -r '.repo_url')
+ GIT_REF=$(echo $BUILD_SOURCE | jq -r '.ref')
+
+ git config --global url."https://github.com/".insteadOf git@github.com:
+ git config --global url."https://".insteadOf git://
+
+ # Example of GIT_URL="https://x-access-token:@github.com/user_name/repo_name"
+ # Example of TRIMMED_URL="https://github.com/user_name/repo_name"
+
+ TOKEN=$(echo "$GIT_URL" | sed -n 's/.*x-access-token:\([^@]*\).*/\1/p')
+ TRIMMED_URL=$(echo "$GIT_URL" | sed 's~x-access-token:[^@]*@~~')
+
+ printf "\033[36m[Start]\033[0m Downloading source code from $TRIMMED_URL\n"
+
+ # Set auth token
+
+ git config --system credential.helper store
+ echo "https://x-access-token:$TOKEN@github.com" > ~/.git-credentials
+
+ git clone --recursive $TRIMMED_URL source-code
+ cd source-code && git reset --hard $GIT_REF
+ elif [[ $BUILD_TYPE == "bitbucket" ]]; then
+ GIT_URL=$(echo $BUILD_SOURCE | jq -r '.repo_url')
+ GIT_REF=$(echo $BUILD_SOURCE | jq -r '.ref')
+
+ git config --global url."https://bitbucket.org/".insteadOf git@bitbucket.org:
+ git config --global url."https://".insteadOf git://
+
+ # Example of GIT_URL="https://x-token-auth:@bitbucket.org/user_name/repo_name"
+ # Example of TRIMMED_URL="https://bitbucket.org/user_name/repo_name"
+
+ TOKEN=$(echo "$GIT_URL" | sed -n 's/.*x-token-auth:\([^@]*\).*/\1/p')
+ TRIMMED_URL=$(echo "$GIT_URL" | sed 's~x-token-auth:[^@]*@~~')
+
+ printf "\033[36m[Start]\033[0m Downloading source code from $TRIMMED_URL\n"
+
+ # Set auth token
+
+ git config --system credential.helper store
+ echo "https://x-token-auth:$TOKEN@bitbucket.org" > ~/.git-credentials
+
+ git clone --recurse-submodules $TRIMMED_URL source-code
+ cd source-code && git reset --hard $GIT_REF
+ elif [[ $BUILD_TYPE == "gitlab" ]]; then
+ GIT_URL=$(echo $BUILD_SOURCE | jq -r '.repo_url')
+ GIT_REF=$(echo $BUILD_SOURCE | jq -r '.ref')
+
+ git config --global url."https://gitlab.com/".insteadOf git@gitlab.com:
+ git config --global url."https://".insteadOf git://
+
+ # Example of GIT_URL="https://oauth2:@gitlab.com/user_name/repo_name"
+ # Example of TRIMMED_URL="https://gitlab.com/user_name/repo_name"
+
+ TOKEN=$(echo "$GIT_URL" | sed -n 's/.*oauth2:\([^@]*\).*/\1/p')
+ TRIMMED_URL=$(echo "$GIT_URL" | sed 's~oauth2:[^@]*@~~')
+
+ printf "\033[36m[Start]\033[0m Downloading source code from $TRIMMED_URL\n"
+
+ # Set auth token
+
+ git config --system credential.helper store
+ echo "https://oauth2:$TOKEN@gitlab.com" > ~/.git-credentials
+
+ git clone --recurse-submodules $TRIMMED_URL source-code
+ cd source-code && git reset --hard $GIT_REF
+ elif [[ $BUILD_TYPE == "notebook_build" ]]; then
+ :
+ else
+ printf "{{ .Values.truefoundryWorkflows.logMarkers.error }} Source type '$BUILD_TYPE' not supported.\n"
+ exit 1
+ fi
+ printf "{{ .Values.truefoundryWorkflows.logMarkers.done }} Download code completed\n"
+ printf "\033[36m[Start]\033[0m Building and pushing the docker container. Please find the logs below\n"
+
+ DOCKER_PASSWORD=$(echo '{{`{{inputs.parameters.dockerRegistryPassword}}`}}' | base64 -d)
+
+ docker login -u "{{`{{inputs.parameters.dockerRegistryUsername}}`}}" -p $DOCKER_PASSWORD "{{`{{inputs.parameters.dockerRegistryURL}}`}}" 2> /dev/null
+
+ IMAGE="{{`{{inputs.parameters.dockerRegistryURL}}`}}"/"{{`{{inputs.parameters.dockerRepo}}`}}"
+
+ printf "\033[36m[==== Docker logs start ====]\033[0m\n"
+ docker buildx create --name remote-kubernetes --driver remote tcp://{{`{{inputs.parameters.buildkitServiceURL}}`}}
+ # image-manifest=true is needed for ecr and works for others - https://github.com/aws/containers-roadmap/issues/876#issuecomment-1665121877
+ sfy build --build-config={{`{{inputs.parameters.buildConfig}}`}} --name=$IMAGE:"{{`{{inputs.parameters.dockerTag}}`}}" --tag=$IMAGE:"{{`{{inputs.parameters.dockerTag}}`}}" --tag=$IMAGE:latest --cache-to=type=registry,ref=$IMAGE:cache-latest,image-manifest=true,mode=max --cache-from=type=registry,ref=$IMAGE:cache-latest --build-context tfy-secrets=/var/run/secrets/ --builder=remote-kubernetes --push
+ printf "\033[36m[==== Docker logs end ====]\033[0m\n"
+ printf "{{ .Values.truefoundryWorkflows.logMarkers.done }} Docker image built and pushed\n"
+ volumeMounts:
+ - name: workdir
+ mountPath: /mnt/vol
+ - name: truefoundry-docker-config
+ mountPath: /root/.truefoundry/.docker/
+ {{- with .Values.truefoundryWorkflows.extraVolumeMounts }}
+ {{- toYaml . | nindent 6 }}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.truefoundryWorkflows.sfyBuilder.resources | nindent 8 }}
+ - name: exit-handler
+ inputs:
+ parameters:
+ - name: callbackURL
+ - name: dockerRegistryURL
+ - name: dockerRepo
+ - name: dockerTag
+ - name: dockerRegistryUsername
+ - name: dockerRegistryPassword
+ steps:
+ - - name: success-callback
+ when: "{{`{{workflow.status}}`}} == Succeeded"
+ template: send-api-request
+ arguments:
+ parameters:
+ - name: url
+ value: "{{`{{inputs.parameters.callbackURL}}`}}"
+ - name: method
+ value: "PATCH"
+ - name: payload
+ value: '{"status": "SUCCEEDED", "imageUri": "{{`{{inputs.parameters.dockerRegistryURL}}`}}/{{`{{inputs.parameters.dockerRepo}}`}}:{{`{{inputs.parameters.dockerTag}}`}}"}'
+ - name: token
+ value: ""
+ - name: failure-callback
+ when: "{{`{{workflow.status}}`}} != Succeeded"
+ template: send-api-request
+ arguments:
+ parameters:
+ - name: url
+ value: "{{`{{inputs.parameters.callbackURL}}`}}"
+ - name: method
+ value: "PATCH"
+ - name: payload
+ value: '{"status": "FAILED"}'
+ - name: token
+ value: ""
+ - - name: end-marker
+ template: end-marker
+ - - name: should-build-soci-index
+ template: should-build-soci-index
+ when: >-
+ '{{ .Values.truefoundryWorkflows.sociIndexBuildAndPush.enabled }}' == 'true'
+ &&
+ {{`{{workflow.status}}`}} == Succeeded
+ arguments:
+ parameters:
+ - name: dockerRegistryURL
+ value: "{{`{{inputs.parameters.dockerRegistryURL}}`}}"
+ - name: dockerRegistryUsername
+ value: "{{`{{inputs.parameters.dockerRegistryUsername}}`}}"
+ - name: dockerRegistryPassword
+ value: "{{`{{inputs.parameters.dockerRegistryPassword}}`}}"
+ - name: dockerRepo
+ value: "{{`{{inputs.parameters.dockerRepo}}`}}"
+ - name: dockerTag
+ value: "{{`{{inputs.parameters.dockerTag}}`}}"
+ - - name: build-and-push-soci-index
+ template: build-and-push-soci-index
+ when: >-
+ {{`{{steps.should-build-soci-index.status}}`}} == Succeeded
+ &&
+ '{{`{{steps.should-build-soci-index.outputs.parameters.result}}`}}' == 'true'
+ arguments:
+ parameters:
+ - name: dockerRegistryURL
+ value: "{{`{{inputs.parameters.dockerRegistryURL}}`}}"
+ - name: dockerRegistryUsername
+ value: "{{`{{inputs.parameters.dockerRegistryUsername}}`}}"
+ - name: dockerRegistryPassword
+ value: "{{`{{inputs.parameters.dockerRegistryPassword}}`}}"
+ - name: dockerRepo
+ value: "{{`{{inputs.parameters.dockerRepo}}`}}"
+ - name: dockerTag
+ value: "{{`{{inputs.parameters.dockerTag}}`}}"
+ - name: end-marker
+ retryStrategy:
+ limit: 5
+ retryPolicy: "Always"
+ backoff:
+ duration: "30"
+ factor: 2
+ maxDuration: "2m"
+ script:
+ resources:
+ limits:
+ cpu: 200m
+ ephemeral-storage: 256Mi
+ memory: 256Mi
+ requests:
+ cpu: 100m
+ ephemeral-storage: 128Mi
+ memory: 128Mi
+ image: ubuntu
+ command: [bash]
+ source: |
+ #!/bin/bash
+ set -e
+ if [[ "{{`{{workflow.status}}`}}" == "Succeeded" ]]; then
+ echo -e "{{ .Values.truefoundryWorkflows.logMarkers.done }} Image Built Successfully."
+ echo -e "{{ .Values.truefoundryWorkflows.logMarkers.done }} Kubernetes deployment triggered. It may take 5-10s for the application to be live."
+ else
+ echo -e "{{ .Values.truefoundryWorkflows.logMarkers.error }} Error occured while building and pushing docker image."
+ echo -e "{{ .Values.truefoundryWorkflows.logMarkers.error }} Build Image Failed."
+ fi
+ echo "PIPELINE_RUN_{{`{{workflow.name}}`}}_ENDED"
+ - name: send-api-request
+ retryStrategy:
+ limit: 20
+ retryPolicy: "Always"
+ backoff:
+ duration: "30"
+ factor: 2
+ maxDuration: "2m"
+ inputs:
+ parameters:
+ - name: url
+ - name: method
+ - name: payload
+ - name: token
+ {{- with .Values.truefoundryWorkflows.extraVolumes }}
+ volumes:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ script:
+ resources:
+ limits:
+ cpu: 200m
+ ephemeral-storage: 256Mi
+ memory: 256Mi
+ requests:
+ cpu: 100m
+ ephemeral-storage: 128Mi
+ memory: 128Mi
+ image: nyurik/alpine-python3-requests
+ command: [python3]
+ {{- with .Values.truefoundryWorkflows.extraEnvs }}
+ env:
+ {{- toYaml . | nindent 6 }}
+ {{- end }}
+ source: |
+ import logging
+ import requests
+ import sys
+ import time
+ import json
+
+ def api_call():
+ try:
+ payload = '{{`{{inputs.parameters.payload}}`}}'
+ url= "{{`{{inputs.parameters.url}}`}}"
+ method= "{{`{{inputs.parameters.method}}`}}"
+ token= "{{`{{inputs.parameters.token}}`}}"
+ msg = "\033[36m[Start]\033[0m Sending request to url: {} with json {}".format(url, payload)
+ print(msg)
+ r = requests.request(method, url=url, json=json.loads(payload), headers={"authorization": "Bearer "+ token})
+ r.raise_for_status()
+ except Exception as e:
+ print("{{ .Values.truefoundryWorkflows.logMarkers.error }} Error occured while notifying server")
+ print("Error occured", e)
+ time.sleep(60)
+ sys.exit(1)
+ api_call()
+ {{- with .Values.truefoundryWorkflows.extraVolumeMounts }}
+ volumeMounts:
+ {{- toYaml . | nindent 6 }}
+ {{- end }}
+ - name: should-build-soci-index
+ activeDeadlineSeconds: 1800
+ metrics:
+ prometheus:
+ - name: tfy_build_soci_index_status
+ help: "SOCI index build and push status"
+ labels:
+ - key: name
+ value: "{{`{{steps.name}}`}}"
+ - key: status
+ value: "{{`{{status}}`}}"
+ when: "{{`{{status}}`}} != Skipped"
+ counter:
+ value: "1"
+ - name: tfy_build_soci_index_duration_sec
+ help: "SOCI index build and push duration"
+ labels:
+ - key: name
+ value: "{{`{{steps.name}}`}}"
+ - key: status
+ value: "{{`{{status}}`}}"
+ when: "{{`{{status}}`}} != Skipped"
+ gauge:
+ value: "{{`{{duration}}`}}"
+ inputs:
+ parameters:
+ - name: dockerRegistryURL
+ - name: dockerRegistryUsername
+ - name: dockerRegistryPassword
+ - name: dockerRepo
+ - name: dockerTag
+ retryStrategy:
+ backoff:
+ duration: '1'
+ factor: 2
+ maxDuration: 1m
+ limit: 5
+ retryPolicy: Always
+ outputs:
+ parameters:
+ - name: result
+ valueFrom:
+ path: /tmp/result
+ script:
+ command: [bash]
+ image: {{ .Values.truefoundryWorkflows.sociIndexBuildAndPush.image }}
+ resources:
+ requests:
+ cpu: 50m
+ ephemeral-storage: 10Mi
+ memory: 50Mi
+ limits:
+ cpu: 50m
+ ephemeral-storage: 10Mi
+ memory: 50Mi
+ source: |
+ #!/bin/bash
+
+ set -eu -o pipefail
+
+ ENCODED_PASSWORD="{{`{{inputs.parameters.dockerRegistryPassword}}`}}"
+ PASSWORD=$(echo $ENCODED_PASSWORD | base64 -d)
+ USERNAME="{{`{{inputs.parameters.dockerRegistryUsername}}`}}"
+ REGISTRY="{{`{{inputs.parameters.dockerRegistryURL}}`}}"
+ REPOSITORY="{{`{{inputs.parameters.dockerRepo}}`}}"
+ TAG="{{`{{inputs.parameters.dockerTag}}`}}"
+ IMAGE=$REGISTRY/$REPOSITORY:$TAG
+ IMAGE_SIZE_THRESHOLD=$(printf '%.0f' {{ .Values.truefoundryWorkflows.sociIndexBuildAndPush.imageSizeThresholdBytes | quote }})
+
+ docker login -u $USERNAME -p $PASSWORD $REGISTRY 2> /dev/null
+
+ echo Registry is $REGISTRY
+
+ if [[ $REGISTRY != *"amazonaws.com"* ]]; then
+ echo Registry is not from ECR. Skipping SOCI index creation.
+ echo -n "false" > /tmp/result
+ exit 0
+ fi
+
+ MANFEST=$(docker manifest inspect --verbose $IMAGE)
+ IMAGE_SIZE=$(echo $MANFEST | jq '.[] | .OCIManifest.layers | .[] | select(.mediaType | contains("oci.image.layer.v1.tar+gzip")) | .size' | awk '{sum+=$0} END{print sum}')
+ echo Image Size: $IMAGE_SIZE
+ echo Threshold: $IMAGE_SIZE_THRESHOLD
+
+ if [[ "$IMAGE_SIZE" -lt "$IMAGE_SIZE_THRESHOLD" ]]; then
+ echo Image size is less than $IMAGE_SIZE_THRESHOLD. Skipping SOCI index creation.
+ echo -n "false" > /tmp/result
+ exit 0
+ fi
+
+ echo SOCI index will be built and pushed.
+ echo -n "true" > /tmp/result
+ - name: build-and-push-soci-index
+ activeDeadlineSeconds: 3600
+ metrics:
+ prometheus:
+ - name: tfy_build_soci_index_status
+ help: "SOCI index build and push status"
+ labels:
+ - key: name
+ value: "{{`{{steps.name}}`}}"
+ - key: status
+ value: "{{`{{status}}`}}"
+ when: "{{`{{status}}`}} != Skipped"
+ counter:
+ value: "1"
+ - name: tfy_build_soci_index_duration_sec
+ help: "SOCI index build and push duration"
+ labels:
+ - key: name
+ value: "{{`{{steps.name}}`}}"
+ - key: status
+ value: "{{`{{status}}`}}"
+ when: "{{`{{status}}`}} != Skipped"
+ gauge:
+ value: "{{`{{duration}}`}}"
+ inputs:
+ parameters:
+ - name: dockerRegistryURL
+ - name: dockerRegistryUsername
+ - name: dockerRegistryPassword
+ - name: dockerRepo
+ - name: dockerTag
+ retryStrategy:
+ backoff:
+ duration: '1'
+ factor: 2
+ maxDuration: 1m
+ limit: 2
+ retryPolicy: Always
+ script:
+ command: [bash]
+ image: {{ .Values.truefoundryWorkflows.sociIndexBuildAndPush.image }}
+ resources:
+ requests:
+ cpu: 500m
+ ephemeral-storage: 10Gi
+ memory: 700Mi
+ limits:
+ cpu: 1000m
+ ephemeral-storage: 30Gi
+ memory: 1024Mi
+ securityContext:
+ privileged: true
+ source: |
+ #!/bin/bash
+
+ set -eu -o pipefail
+
+ ENCODED_PASSWORD="{{`{{inputs.parameters.dockerRegistryPassword}}`}}"
+ PASSWORD=$(echo $ENCODED_PASSWORD | base64 -d)
+ USERNAME="{{`{{inputs.parameters.dockerRegistryUsername}}`}}"
+ REGISTRY="{{`{{inputs.parameters.dockerRegistryURL}}`}}"
+ REPOSITORY="{{`{{inputs.parameters.dockerRepo}}`}}"
+ TAG="{{`{{inputs.parameters.dockerTag}}`}}"
+ IMAGE=$REGISTRY/$REPOSITORY:$TAG
+
+ docker login -u $USERNAME -p $PASSWORD $REGISTRY 2> /dev/null
+
+ echo Starting Containerd
+ containerd > /dev/null 2>&1 &
+ sleep 3
+ ctr version > /dev/null
+
+ echo Pulling Container Image $IMAGE
+
+ time ctr content fetch -u "$USERNAME:$PASSWORD" \
+ --platform=linux/amd64 \
+ $IMAGE > /dev/null
+
+
+ echo Creating Soci Index
+
+ time soci create --platform=linux/amd64 $IMAGE
+
+ echo Pushing Soci Index
+ time soci push --platform=linux/amd64 $IMAGE
+
+ echo Done!
+ {{- with .Values.truefoundryWorkflows.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .Values.truefoundryWorkflows.affinity }}
+ affinity:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ {{- with .Values.truefoundryWorkflows.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
diff --git a/charts/tfy-build/values.yaml b/charts/tfy-build/values.yaml
new file mode 100644
index 00000000..49ef1e42
--- /dev/null
+++ b/charts/tfy-build/values.yaml
@@ -0,0 +1,38 @@
+global: {}
+nameOverride: ''
+fullnameOverride: ''
+serviceAccount:
+ create: true
+ name: tfy-build
+ annotations: {}
+truefoundryWorkflows:
+ sfyBuilder:
+ version: 0.7.3
+ resources:
+ limits:
+ cpu: 1
+ ephemeral-storage: 20Gi
+ memory: 2Gi
+ requests:
+ cpu: 200m
+ ephemeral-storage: 10Gi
+ memory: 500Mi
+ extraEnvs: []
+ extraVolumeMounts: []
+ extraVolumes: []
+ affinity: {}
+ tolerations: {}
+ nodeSelector: {}
+ logMarkers:
+ error: \u001b[31m[Error]\u001b[0m
+ done: \u001b[32m[Done]\u001b[0m
+ start: \u001b[36m[Start]\u001b[0m
+ clientPrefix:
+ - TFY-CLIENT
+ supportSlack: >-
+ https://join.slack.com/t/truefoundry/shared_invite/zt-11ht512jq-nDJq~HJMqc6wBw90JVlo7g
+ serviceFoundryUiUrl: https://app.truefoundry.com/workspace
+ sociIndexBuildAndPush:
+ enabled: false
+ image: public.ecr.aws/truefoundrycloud/soci-index-builder:0.2.0-rc.1
+ imageSizeThresholdBytes: 419430400
diff --git a/charts/tfy-controller/Chart.yaml b/charts/tfy-controller/Chart.yaml
new file mode 100644
index 00000000..44f97817
--- /dev/null
+++ b/charts/tfy-controller/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: tfy-controller
+version: 0.0.19-rc.2
+description: Deployment control loop and Proxy Server Chart"
+maintainers:
+ - name: truefoundry
diff --git a/charts/tfy-controller/templates/_helpers.tpl b/charts/tfy-controller/templates/_helpers.tpl
new file mode 100644
index 00000000..4f5316fb
--- /dev/null
+++ b/charts/tfy-controller/templates/_helpers.tpl
@@ -0,0 +1,100 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create a default fully qualified app name.
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+ If release name contains chart name it will be used as a full name.
+ */}}
+{{- define "app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Create chart name and version as used by the chart label.
+ */}}
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Common labels
+ */}}
+{{- define "app.labels" -}}
+helm.sh/chart: {{ include "app.chart" . }}
+{{- range $name, $value := .Values.commonLabels }}
+{{ $name }}: {{ tpl $value $ | quote }}
+{{- end }}
+{{ include "app.selectorLabels" . }}
+{{- if .Values.imageTag }}
+app.kubernetes.io/version: {{ .Values.imageTag | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+ Selector labels
+ */}}
+{{- define "app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+ Create the name of the service account to use
+ */}}
+{{- define "app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Parse env from template
+ */}}
+{{- define "app.parseEnv" -}}
+{{ tpl (.Values.env | toYaml) . }}
+{{- end }}
+
+{{/*
+ Create the env file
+ */}}
+{{- define "app.env" }}
+{{- range $key, $val := (include "app.parseEnv" .) | fromYaml }}
+{{- if and $val (contains "${k8s-secret" ($val | toString)) }}
+{{- if eq (regexSplit "/" $val -1 | len) 2 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ $.Values.envSecretName }}
+ key: {{ index (regexSplit "/" $val -1) 1 | trimSuffix "}" }}
+{{- else if eq (regexSplit "/" $val -1 | len) 3 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ index (regexSplit "/" $val -1) 1 }}
+ key: {{ index (regexSplit "/" $val -1) 2 | trimSuffix "}" }}
+{{- else }}
+{{- fail "Invalid secret supplied" }}
+{{- end }}
+{{- else }}
+- name: {{ $key }}
+ value: {{ $val | quote }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/tfy-controller/templates/deployment.yaml b/charts/tfy-controller/templates/deployment.yaml
new file mode 100644
index 00000000..61a848ef
--- /dev/null
+++ b/charts/tfy-controller/templates/deployment.yaml
@@ -0,0 +1,59 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ {{- include "app.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "app.labels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "app.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ env:
+ {{- include "app.env" . | trim | nindent 12 }}
+ image: "{{ .Values.imageRepository }}:{{ .Values.imageTag }}"
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ ports:
+ - name: port-{{ .Values.service.port }}
+ containerPort: {{ .Values.service.port }}
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- if .Values.healthcheck.enabled }}
+ livenessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.liveness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ readinessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.readiness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/charts/tfy-controller/templates/service.yaml b/charts/tfy-controller/templates/service.yaml
new file mode 100644
index 00000000..17692108
--- /dev/null
+++ b/charts/tfy-controller/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: {{ .Values.service.port }}
+ protocol: TCP
+ name: port-{{ .Values.service.port }}
+ selector:
+ {{- include "app.selectorLabels" . | nindent 4 }}
diff --git a/charts/tfy-controller/templates/serviceaccount.yaml b/charts/tfy-controller/templates/serviceaccount.yaml
new file mode 100644
index 00000000..a41b8ac6
--- /dev/null
+++ b/charts/tfy-controller/templates/serviceaccount.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "app.serviceAccountName" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations:
+{{ tpl (toYaml . | indent 4) $ }}
+{{- end }}
+imagePullSecrets:
+{{- if .Values.global.existingTruefoundryImagePullSecretName }}
+ - name: {{ .Values.global.existingTruefoundryImagePullSecretName }}
+{{- else }}
+ - name: truefoundry-image-pull-secret
+{{- end }}
+{{- end }}
diff --git a/charts/tfy-controller/values.yaml b/charts/tfy-controller/values.yaml
new file mode 100644
index 00000000..c71222c3
--- /dev/null
+++ b/charts/tfy-controller/values.yaml
@@ -0,0 +1,56 @@
+global: {}
+imageRepository: truefoundrycloud/tfy-controller
+environmentName: default
+envSecretName: sfy-manifest-service-env-secret
+imagePullPolicy: IfNotPresent
+nameOverride: ''
+fullnameOverride: ''
+podAnnotations: {}
+podSecurityContext: {}
+commonLabels: {}
+securityContext: {}
+healthcheck:
+ enabled: false
+resources:
+ limits:
+ cpu: 200m
+ memory: 256Mi
+ ephemeral-storage: 256Mi
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ ephemeral-storage: 128Mi
+nodeSelector: {}
+tolerations: {}
+affinity: {}
+service:
+ type: ClusterIP
+ port: 8123
+ annotations: {}
+serviceAccount:
+ create: true
+ name: tfy-controller
+ annotations: {}
+env:
+ GIN_MODE: release
+ SFY_SERVER_URL: >-
+ http://{{ .Release.Name }}-servicefoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:3000
+ SFY_API_KEY: ${k8s-secret/truefoundry-creds/TFY_API_KEY}
+ SFY_MANIFEST_SERVER_URL: >-
+ http://{{ .Release.Name }}-sfy-manifest-service.{{ .Release.Namespace
+ }}.svc.cluster.local:8080
+ PROXY_SERVER_PORT: '{{ .Values.service.port }}'
+ PROXY_SERVER_ENABLED: 'true'
+ DEPLOYMENT_CONTROLLER_ENABLED: 'true'
+ MIGRATION_CONTROLLER_ENABLED: 'false'
+ MIGRATION_CONTROLLER_INTERVAL_MINUTES: '60'
+ MIGRATION_CONTROLLER_APPLICATION_HEALTH_CHECK_TIMEOUT_MINUTES: '5'
+ MIGRATION_CONTROLLER_APPLICATION_HEALTH_CHECK_INTERVAL_SECONDS: '20'
+ TENANT_NAME: '{{ .Values.global.tenantName }}'
+ AUTH_SERVER_URL: https://auth.truefoundry.com
+ TFY_AGENT_STATE_BUFFER_PROCESSOR_ENABLED: 'true'
+ TFY_AGENT_STATE_BUFFER_PROCESSOR_NATS_URL: >-
+ nats://{{ .Release.Name }}-nats.{{ .Release.Namespace
+ }}.svc.cluster.local:4222
+imageTag: dc8765d988fd8d0c38ff73aaf9ba085b9c75f553
diff --git a/charts/truefoundry-frontend-app/Chart.yaml b/charts/truefoundry-frontend-app/Chart.yaml
new file mode 100644
index 00000000..88757b2e
--- /dev/null
+++ b/charts/truefoundry-frontend-app/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: truefoundry-frontend-app
+version: 0.3.134-rc.4
+description: "Truefoundry-frontend-app deployment chart"
+maintainers:
+ - name: truefoundry
diff --git a/charts/truefoundry-frontend-app/templates/_helpers.tpl b/charts/truefoundry-frontend-app/templates/_helpers.tpl
new file mode 100644
index 00000000..4f5316fb
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/_helpers.tpl
@@ -0,0 +1,100 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Create a default fully qualified app name.
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+ If release name contains chart name it will be used as a full name.
+ */}}
+{{- define "app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Create chart name and version as used by the chart label.
+ */}}
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+ Common labels
+ */}}
+{{- define "app.labels" -}}
+helm.sh/chart: {{ include "app.chart" . }}
+{{- range $name, $value := .Values.commonLabels }}
+{{ $name }}: {{ tpl $value $ | quote }}
+{{- end }}
+{{ include "app.selectorLabels" . }}
+{{- if .Values.imageTag }}
+app.kubernetes.io/version: {{ .Values.imageTag | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+ Selector labels
+ */}}
+{{- define "app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+ Create the name of the service account to use
+ */}}
+{{- define "app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
+{{/*
+ Parse env from template
+ */}}
+{{- define "app.parseEnv" -}}
+{{ tpl (.Values.env | toYaml) . }}
+{{- end }}
+
+{{/*
+ Create the env file
+ */}}
+{{- define "app.env" }}
+{{- range $key, $val := (include "app.parseEnv" .) | fromYaml }}
+{{- if and $val (contains "${k8s-secret" ($val | toString)) }}
+{{- if eq (regexSplit "/" $val -1 | len) 2 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ $.Values.envSecretName }}
+ key: {{ index (regexSplit "/" $val -1) 1 | trimSuffix "}" }}
+{{- else if eq (regexSplit "/" $val -1 | len) 3 }}
+- name: {{ $key }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ index (regexSplit "/" $val -1) 1 }}
+ key: {{ index (regexSplit "/" $val -1) 2 | trimSuffix "}" }}
+{{- else }}
+{{- fail "Invalid secret supplied" }}
+{{- end }}
+{{- else }}
+- name: {{ $key }}
+ value: {{ $val | quote }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/truefoundry-frontend-app/templates/deployment.yaml b/charts/truefoundry-frontend-app/templates/deployment.yaml
new file mode 100644
index 00000000..c1bf9893
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/deployment.yaml
@@ -0,0 +1,67 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "app.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "app.labels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ include "app.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ env:
+ {{- include "app.env" . | trim | nindent 12 }}
+ image: "{{ .Values.imageRepository }}:{{ .Values.imageTag }}"
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.service.port }}
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- if .Values.healthcheck.enabled }}
+ livenessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.liveness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ readinessProbe:
+ httpGet:
+ path: {{ .Values.healthcheck.readiness.path }}
+ port: {{ .Values.healthcheck.liveness.port }}
+ {{- end }}
+ volumeMounts:
+ {{- toYaml .Values.extraVolumeMounts | nindent 12 }}
+ volumes:
+ {{- toYaml .Values.extraVolumes | nindent 8 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.topologySpreadConstraints }}
+ topologySpreadConstraints:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
\ No newline at end of file
diff --git a/charts/truefoundry-frontend-app/templates/ingress.yaml b/charts/truefoundry-frontend-app/templates/ingress.yaml
new file mode 100644
index 00000000..1fe0c59d
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/ingress.yaml
@@ -0,0 +1,39 @@
+{{- if .Values.ingress.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+{{- if .Values.ingress.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.ingress.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+{{- end }}
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.ingress.labels }}
+ {{- toYaml .Values.ingress.labels | nindent 4 }}
+ {{- end }}
+spec:
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+ rules:
+ {{- range $host := .Values.ingress.hosts }}
+ - host: {{ $host }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ $serviceName }}
+ port:
+ number: {{ $servicePort }}
+
+ {{- end -}}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- toYaml .Values.ingress.tls | nindent 4 }}
+ {{- end -}}
+{{- end -}}
diff --git a/charts/truefoundry-frontend-app/templates/llm-gateway-destination-rule.yaml b/charts/truefoundry-frontend-app/templates/llm-gateway-destination-rule.yaml
new file mode 100644
index 00000000..7462a030
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/llm-gateway-destination-rule.yaml
@@ -0,0 +1,15 @@
+{{- if .Values.llmGateway.external }}
+apiVersion: networking.istio.io/v1beta1
+kind: DestinationRule
+metadata:
+ name: llm-gateway-{{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ namespace: {{ .Release.Namespace }}
+spec:
+ host: {{ tpl .Values.llmGateway.backendHost . }}
+ trafficPolicy:
+ tls:
+ mode: SIMPLE
+ sni: {{ tpl .Values.llmGateway.backendHost . }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/truefoundry-frontend-app/templates/llm-gateway-service-entry.yaml b/charts/truefoundry-frontend-app/templates/llm-gateway-service-entry.yaml
new file mode 100644
index 00000000..178e66ee
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/llm-gateway-service-entry.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.llmGateway.external }}
+apiVersion: networking.istio.io/v1beta1
+kind: ServiceEntry
+metadata:
+ name: llm-gateway-{{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ namespace: {{ .Release.Namespace }}
+spec:
+ hosts:
+ - {{ tpl .Values.llmGateway.backendHost . }}
+ location: MESH_EXTERNAL
+ ports:
+ - number: {{ .Values.llmGateway.backendPort }}
+ protocol: HTTPS
+ name: https-port
+ resolution: DNS
+{{- end }}
\ No newline at end of file
diff --git a/charts/truefoundry-frontend-app/templates/service.yaml b/charts/truefoundry-frontend-app/templates/service.yaml
new file mode 100644
index 00000000..a45d8822
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: {{ .Values.service.port }}
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "app.selectorLabels" . | nindent 4 }}
\ No newline at end of file
diff --git a/charts/truefoundry-frontend-app/templates/serviceaccount.yaml b/charts/truefoundry-frontend-app/templates/serviceaccount.yaml
new file mode 100644
index 00000000..a41b8ac6
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/serviceaccount.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "app.serviceAccountName" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations:
+{{ tpl (toYaml . | indent 4) $ }}
+{{- end }}
+imagePullSecrets:
+{{- if .Values.global.existingTruefoundryImagePullSecretName }}
+ - name: {{ .Values.global.existingTruefoundryImagePullSecretName }}
+{{- else }}
+ - name: truefoundry-image-pull-secret
+{{- end }}
+{{- end }}
diff --git a/charts/truefoundry-frontend-app/templates/virtualservice.yaml b/charts/truefoundry-frontend-app/templates/virtualservice.yaml
new file mode 100644
index 00000000..8738663b
--- /dev/null
+++ b/charts/truefoundry-frontend-app/templates/virtualservice.yaml
@@ -0,0 +1,65 @@
+{{- if .Values.istio.virtualservice.enabled -}}
+{{- $serviceName := include "app.fullname" . -}}
+{{- $servicePort := .Values.service.port -}}
+apiVersion: networking.istio.io/v1beta1
+kind: VirtualService
+metadata:
+ name: {{ include "app.fullname" . }}
+ labels:
+ {{- include "app.labels" . | nindent 4 }}
+ {{- if .Values.istio.virtualservice.annotations }}
+ annotations:
+ {{- range $key, $value := .Values.istio.virtualservice.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ namespace: {{ .Release.Namespace }}
+spec:
+ gateways:
+ {{- range .Values.istio.virtualservice.gateways}}
+ - {{ . }}
+ {{- end }}
+ hosts:
+ {{- range .Values.istio.virtualservice.hosts}}
+ - {{ . }}
+ {{- end }}
+ http:
+ - match:
+ - uri:
+ prefix: "/api/svc/socket.io"
+ rewrite:
+ uri: /socket.io
+ route:
+ - destination:
+ host: {{ tpl .Values.servicefoundryServerHost . }}
+ port:
+ number: 3000
+ - match:
+ - uri:
+ prefix: "/api/llm/"
+ rewrite:
+ uri: /
+ {{- if .Values.llmGateway.external }}
+ authority: {{ tpl .Values.llmGateway.backendHost . }}
+ {{- end }}
+ route:
+ - destination:
+ host: {{ tpl .Values.llmGateway.backendHost . }}
+ port:
+ number: {{ .Values.llmGateway.backendPort }}
+ - match:
+ - uri:
+ prefix: /api/proxy-server/
+ rewrite:
+ uri: /
+ route:
+ - destination:
+ host: {{ tpl .Values.proxyServerHost . }}
+ port:
+ number: 8123
+ - route:
+ - destination:
+ host: {{ include "app.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
+ port:
+ number: {{ .Values.service.port }}
+{{- end }}
diff --git a/charts/truefoundry-frontend-app/values.yaml b/charts/truefoundry-frontend-app/values.yaml
new file mode 100644
index 00000000..1217e61c
--- /dev/null
+++ b/charts/truefoundry-frontend-app/values.yaml
@@ -0,0 +1,121 @@
+global: {}
+imageRepository: truefoundrycloud/truefoundry-frontend-app
+replicaCount: 1
+envSecretName: truefoundry-frontend-app-env-secret
+imagePullPolicy: IfNotPresent
+nameOverride: ''
+fullnameOverride: ''
+podAnnotations: {}
+podSecurityContext: {}
+commonLabels: {}
+securityContext: {}
+healthcheck:
+ enabled: false
+resources:
+ limits:
+ cpu: 200m
+ memory: 512Mi
+ ephemeral-storage: 256Mi
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ ephemeral-storage: 128Mi
+nodeSelector: {}
+tolerations: {}
+affinity: {}
+topologySpreadConstraints: {}
+service:
+ type: ClusterIP
+ port: 5000
+ annotations: {}
+ingress:
+ enabled: false
+ annotations: {}
+ labels: {}
+ ingressClassName: istio
+ tls: []
+ hosts: []
+istio:
+ virtualservice:
+ enabled: false
+ annotations: {}
+ gateways: []
+ hosts: []
+serviceAccount:
+ create: true
+ name: truefoundry-frontend-app
+ annotations: {}
+imageTag: e31638986fc7f1e5025987f57b78b0ad864d47ae
+servicefoundryServerHost: >-
+ {{ .Release.Name }}-servicefoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local
+llmGateway:
+ external: false
+ backendHost: '{{ .Release.Name }}-llm-gateway.{{ .Release.Namespace }}.svc.cluster.local'
+ backendPort: 8787
+proxyServerHost: '{{ .Release.Name }}-tfy-controller.{{ .Release.Namespace }}.svc.cluster.local'
+extraVolumes: []
+extraVolumeMounts: []
+env:
+ AUTH_SERVER_URL: https://auth.truefoundry.com
+ NATS_URL: ws://{{ .Release.Name }}-nats.{{ .Release.Namespace }}.svc.cluster.local:443
+ MLFOUNDRY_SERVER_URL: >-
+ http://{{ .Release.Name }}-mlfoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:5000
+ SERVICEFOUNDRY_SERVER_URL: >-
+ http://{{ .Release.Name }}-servicefoundry-server.{{ .Release.Namespace
+ }}.svc.cluster.local:3000
+ TFY_CONTROLLER_URL: >-
+ http://{{ .Release.Name }}-tfy-controller.{{ .Release.Namespace
+ }}.svc.cluster.local:8123
+ VITE_AUTHSERVER_URL: /api/auth
+ VITE_MLFOUNDRY_URL: /api/ml
+ VITE_SVCFOUNDRY_URL: /api/svc
+ VITE_MONITORINGFOUNDRY_URL: /api/monitoring
+ VITE_LLM_PLAYGROUND_API_URL: /api/llm
+ VITE_SOCKET_URL: ''
+ VITE_NATS_URL: ''
+ VITE_FUSIONAUTH_URL: https://login.truefoundry.com
+ VITE_MULTITENANT_ENABLED: 'false'
+ VITE_TENANT_NAME: '{{ .Values.global.tenantName }}'
+ VITE_LOGO_URL: ''
+ VITE_EXPORT_AS_HELM_TYPES: service,volume,helm
+ VITE_ENABLE_COMPANY_REGISTRATION: 'false'
+ VITE_ENABLE_FEATURE_RESOURCE_COSTS: 'false'
+ VITE_STRIPE_PUBLISHABLE_KEY: ''
+ VITE_CREDIT_CARD_REQUIRED_DOMAINS: ''
+ VITE_TENANT_BASE_DOMAIN: ''
+ VITE_MANAGED_CLUSTER_ONBOARDING_ENABLED: 'false'
+ VITE_MANAGED_CLUSTER_ONBOARDING_SERVICE_URL: ''
+ VITE_CIVO_RESOURCES_STRING: ''
+ VITE_CLUSTER_ONBOARDING_FLOW_ENABLED: 'false'
+ VITE_LLM_PLAYGROUND_ENABLED: 'false'
+ VITE_LLM_PLAYGROUND_ENABLE_STANDALONE: 'false'
+ VITE_LLM_PLAYGROUND_ENABLE_REDIRECT: 'false'
+ VITE_OLD_LLM_PLAYGROUND_PATH: llm-playground
+ VITE_LLM_PLAYGROUND_PATH: llm-gateway
+ VITE_ENABLE_SENTRY: 'false'
+ VITE_SENTRY_DSN: ''
+ VITE_APEX_DOMAIN: http://truefoundry.com/
+ VITE_DATAGRID_LICENSE_KEY: >-
+ 1562842fe4dffce93855a342848a3609T1JERVI6NDA5ODIsRVhQSVJZPTE2ODA0NzEzNDkwMDAsS0VZVkVSU0lPTj0x
+ VITE_ENABLE_GOOGLE_ANALYTICS: 'false'
+ VITE_ENABLE_PAGESENSE: 'false'
+ VITE_ENABLE_MIXPANEL: 'false'
+ VITE_SENTRY_AUTH_TOKEN: ''
+ VITE_SENTRY_ENVIRONMENT: ''
+ VITE_MIXPANEL_TOKEN: ''
+ VITE_APP_ENVIRONMENT: ''
+ VITE_CRISP_WEBSITE_ID: ''
+ VITE_QA_FOUNDRY_URL: ''
+ VITE_QA_FOUNDRY_JOB_FQN: ''
+ VITE_QA_FOUNDRY_ML_REPO: ''
+ VITE_QA_FOUNDRY_LLM_HOST: ''
+ VITE_QA_FOUNDRY_LLM_KEY: ''
+ VITE_DOCS_QA_ENABLE_STANDALONE: 'false'
+ VITE_DOCS_QA_DELETE_COLLECTIONS: 'false'
+ VITE_DOCS_QA_STANDALONE_PATH: ''
+ VITE_DOCS_QA_ENABLE_REDIRECT: 'false'
+ VITE_DOCS_QA_EMBEDDINGS: ''
+ VITE_DOCS_QA_MAX_UPLOAD_SIZE_MB: '2'
+ VITE_ENABLE_SUPERFLOW: 'false'
diff --git a/charts/truefoundry/Chart.lock b/charts/truefoundry/Chart.lock
new file mode 100644
index 00000000..3dd47112
--- /dev/null
+++ b/charts/truefoundry/Chart.lock
@@ -0,0 +1,33 @@
+dependencies:
+- name: mlfoundry-server
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.2.103-rc.5
+- name: servicefoundry-server
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.3.140-rc.9
+- name: tfy-configs
+ repository: https://truefoundry.github.io/infra-charts
+ version: 0.1.0-rc.6
+- name: truefoundry-frontend-app
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.3.134-rc.3
+- name: sfy-manifest-service
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.1.119-rc.4
+- name: tfy-build
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.4.3
+- name: nats
+ repository: https://nats-io.github.io/k8s/helm/charts/
+ version: 0.19.1
+- name: llm-gateway
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.2.2
+- name: postgresql
+ repository: oci://registry-1.docker.io/bitnamicharts
+ version: 15.2.2
+- name: tfy-controller
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.0.19-rc.1
+digest: sha256:28a7b05581f0088c4b9665ce82e5411c98b0cd918a01a6ce97624f52ef64f265
+generated: "2024-05-21T20:52:03.681948+05:30"
diff --git a/charts/truefoundry/Chart.yaml b/charts/truefoundry/Chart.yaml
new file mode 100644
index 00000000..4ef4e0a3
--- /dev/null
+++ b/charts/truefoundry/Chart.yaml
@@ -0,0 +1,47 @@
+apiVersion: v2
+name: truefoundry
+version: 0.3.204-rc.18
+description: "Truefoundry applications"
+maintainers:
+ - name: truefoundry
+dependencies:
+ - condition: mlfoundry-server.enabled
+ name: mlfoundry-server
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.2.103-rc.6
+ - condition: servicefoundry-server.enabled
+ name: servicefoundry-server
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.3.140-rc.12
+ - condition: servicefoundry-server.enabled
+ name: tfy-configs
+ repository: https://truefoundry.github.io/infra-charts
+ version: 0.1.0-rc.6
+ - condition: truefoundry-frontend-app.enabled
+ name: truefoundry-frontend-app
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.3.134-rc.3
+ - condition: sfy-manifest-service.enabled
+ name: sfy-manifest-service
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.1.119-rc.4
+ - condition: tfy-build.enabled
+ name: tfy-build
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.4.3
+ - condition: nats.enabled
+ name: nats
+ repository: https://nats-io.github.io/k8s/helm/charts/
+ version: 0.19.1
+ - condition: llm-gateway.enabled
+ name: llm-gateway
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.2.2
+ - condition: global.dev
+ name: postgresql
+ repository: oci://registry-1.docker.io/bitnamicharts
+ version: 15.2.2
+ - name: tfy-controller
+ condition: tfy-controller.enabled
+ repository: oci://quay.io/truefoundrycharts
+ version: 0.0.19-rc.1
diff --git a/charts/truefoundry/README.md b/charts/truefoundry/README.md
new file mode 100644
index 00000000..4ce995c6
--- /dev/null
+++ b/charts/truefoundry/README.md
@@ -0,0 +1,2 @@
+# truefoundry helm chart packaged by TrueFoundry
+truefoundry is an applications that gets deployed on the kubernetes cluster to spin up the TrueFoundry Control plane
\ No newline at end of file
diff --git a/charts/truefoundry/templates/bootstrap/configmap.yaml b/charts/truefoundry/templates/bootstrap/configmap.yaml
new file mode 100644
index 00000000..077de292
--- /dev/null
+++ b/charts/truefoundry/templates/bootstrap/configmap.yaml
@@ -0,0 +1,150 @@
+{{- if .Values.truefoundryBootstrap.enabled }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: truefoundry-bootstrap-cm
+ annotations:
+ "helm.sh/hook": pre-install,pre-upgrade
+ "helm.sh/hook-weight": "-2"
+ "helm.sh/hook-delete-policy": before-hook-creation
+ "argocd.argoproj.io/hook": PreSync
+ "argocd.argoproj.io/sync-wave": "-2"
+ "argocd.argoproj.io/hook-delete-policy": BeforeHookCreation
+data:
+ truefoundry-bootstrap.sh: |
+ #!/bin/bash
+ # This script will output one set of creds in the current directory.
+ # The script creates a nats resolver config file called resolver.conf
+ TRUEFOUNDRY_NATS_SECRET_NAME=truefoundry-nats-secret
+ TRUEFOUNDRY_CREDS_SECRET_NAME=truefoundry-creds
+ print_green() {
+ echo "$(tput setaf 2)$1$(tput sgr0)"
+ }
+ print_yellow() {
+ echo "$(tput setaf 3)$1$(tput sgr0)"
+ }
+ print_red() {
+ echo "$(tput setaf 1)$1$(tput sgr0)"
+ }
+
+ # function to install binaries - kubectl, nsc, helm
+ install_binaries() {
+ apt update && apt install wget unzip -y \
+ && wget https://github.com/nats-io/nsc/releases/download/v2.8.6/nsc-linux-amd64.zip \
+ && unzip nsc-linux-amd64.zip \
+ && mv nsc /usr/bin/ \
+ && wget https://storage.googleapis.com/kubernetes-release/release/v1.29.3/bin/linux/amd64/kubectl \
+ && chmod +x kubectl \
+ && mv kubectl /usr/bin/
+ }
+
+ migrate_nats_seed_to_dedicated_secret() {
+ # Get the value of NATS_CONTROLPLANE_ACCOUNT_SEED from the secret
+ NATS_SEED=$(kubectl -n $TRUEFOUNDRY_NAMESPACE get secret servicefoundry-server-env-secret -o jsonpath='{.data.NATS_CONTROLPLANE_ACCOUNT_SEED}' | base64 --decode)
+
+ # Check if the NATS_SEED is empty
+ if [ -z "$NATS_SEED" ]; then
+ print_red "NATS_CONTROLPLANE_ACCOUNT_SEED is not set in the secret servicefoundry-env-secret."
+ exit 1
+ fi
+
+ # Create the new secret using the NATS_SEED
+ kubectl create secret generic $TRUEFOUNDRY_NATS_SECRET_NAME --from-literal=NATS_CONTROLPLANE_ACCOUNT_SEED="$NATS_SEED" -n $TRUEFOUNDRY_NAMESPACE
+ }
+
+ migrate_truefoundry_creds_to_dedicated_secret() {
+ # Get the value of NATS_CONTROLPLANE_ACCOUNT_SEED from the secret
+ DB_HOST=$(kubectl -n $TRUEFOUNDRY_NAMESPACE get secret servicefoundry-server-env-secret -o jsonpath='{.data.DB_HOST}' | base64 --decode)
+ DB_USERNAME=$(kubectl -n $TRUEFOUNDRY_NAMESPACE get secret servicefoundry-server-env-secret -o jsonpath='{.data.DB_USERNAME}' | base64 --decode)
+ DB_PASSWORD=$(kubectl -n $TRUEFOUNDRY_NAMESPACE get secret servicefoundry-server-env-secret -o jsonpath='{.data.DB_PASSWORD}' | base64 --decode)
+ DB_NAME=$(kubectl -n $TRUEFOUNDRY_NAMESPACE get secret servicefoundry-server-env-secret -o jsonpath='{.data.DB_NAME}' | base64 --decode)
+ TFY_API_KEY=$(kubectl -n $TRUEFOUNDRY_NAMESPACE get secret servicefoundry-server-env-secret -o jsonpath='{.data.SVC_FOUNDRY_SERVICE_API_KEY}' | base64 --decode)
+
+ # Check if the DB creds are empty
+ if [ -z "$DB_HOST" ] || [ -z "$DB_USERNAME" ] || [ -z "$DB_PASSWORD" ] || [ -z "$DB_NAME" ] || [ -z "$TFY_API_KEY" ]; then
+ print_red "DB and Tfy API creds not set in the secret servicefoundry-env-secret"
+ exit 1
+ fi
+ # Create the new secret using the DB creds
+ kubectl create secret generic $TRUEFOUNDRY_CREDS_SECRET_NAME \
+ --from-literal=DB_HOST="$DB_HOST" \
+ --from-literal=DB_USERNAME="$DB_USERNAME" \
+ --from-literal=DB_PASSWORD="$DB_PASSWORD" \
+ --from-literal=DB_NAME="$DB_NAME" \
+ --from-literal=TFY_API_KEY="$TFY_API_KEY" \
+ -n $TRUEFOUNDRY_NAMESPACE
+ }
+
+ # check if the following variables are not set
+ if [ -z "$TRUEFOUNDRY_NAMESPACE" ]; then
+ print_red "TRUEFOUNDRY_NAMESPACE is not set."
+ exit 1
+ fi
+
+ install_binaries
+
+ kubectl -n $TRUEFOUNDRY_NAMESPACE get cm $TRUEFOUNDRY_NATS_CONFIGMAP
+ if [ $? -eq 0 ]; then
+ kubectl -n $TRUEFOUNDRY_NAMESPACE get secret $TRUEFOUNDRY_NATS_SECRET_NAME
+ if [ $? -eq 0 ]; then
+ print_red "Secret $TRUEFOUNDRY_NATS_SECRET_NAME already exists. Exiting..."
+ exit 0
+ else
+ print_yellow "We are going to create the secret $TRUEFOUNDRY_NATS_SECRET_NAME and $TRUEFOUNDRY_CREDS_SECRET_NAME from existing seed. This is a migration scenario dated 2024-05-01"
+ migrate_nats_seed_to_dedicated_secret
+ migrate_truefoundry_creds_to_dedicated_secret
+ exit 0
+ fi
+ fi
+ print_yellow "$TRUEFOUNDRY_NATS_CONFIGMAP not found. Creating NATS account and configmap..."
+
+ # Setup NSC env
+ NSC_ROOT=$(pwd)/nsc
+ export NKEYS_PATH=$NSC_ROOT/nkeys
+ export NSC_HOME=$NSC_ROOT/accounts
+ nsc env -s "${NSC_HOME}/nats"
+ nsc env
+
+ # Create Operator
+ nsc add operator --sys --name truefoundry
+
+ # Create tfy-controlplane account. The seed for this account is provided as an environment variable
+ # to servicefoundry-server
+ nsc add account --name tfy-controlplane
+ # enable JS
+ nsc edit account --name tfy-controlplane --js-disk-storage 512M
+
+ # Create user to create a stream.
+ nsc add user --account tfy-controlplane --name js-creator
+ nsc generate creds > "${NSC_ROOT}/user.creds"
+
+ # Store account info.
+ nsc generate config --mem-resolver --config-file "${NSC_ROOT}/resolver.conf"
+
+ # Get seed of the account
+ NKEYS_EXPORT_DIR=$NSC_ROOT/exported-keys
+ nsc export keys --account tfy-controlplane --accounts --dir "${NKEYS_EXPORT_DIR}"
+ NKEYS_FILE_NAME=$(ls "${NKEYS_EXPORT_DIR}" | grep "A*.nk" | head -1)
+ NKEYS_PATH="${NKEYS_EXPORT_DIR}/${NKEYS_FILE_NAME}"
+ SEED=$(cat "${NKEYS_PATH}")
+ cat "${NKEYS_PATH}" > nsc/tfy.seed
+
+ # Create K8s config map to store the account resolver.
+ # This will be imported by the main config file.
+ kubectl create configmap $TRUEFOUNDRY_NATS_CONFIGMAP --from-file "nsc/resolver.conf" -n $TRUEFOUNDRY_NAMESPACE -o yaml --dry-run | kubectl apply -f -
+
+ # copy the nats seed to /tfy.seed
+ NATS_SEED=$(cat nsc/tfy.seed)
+
+ # creating the secret
+ kubectl create -f -<
+ tolerations:
+ - key: class.truefoundry.io/control-plane
+ effect: NoSchedule
+ operator: Exists
+ - key: "cloud.google.com/gke-spot"
+ value: "true"
+ effect: NoSchedule
+ operator: Equal
+ - key: kubernetes.azure.com/scalesetpriority
+ value: spot
+ effect: NoSchedule
+ operator: Equal
+
+#############################
+# Settings corresponding to the NATS server
+nats:
+ enabled: true
+ tolerations:
+ - key: class.truefoundry.io/control-plane
+ effect: NoSchedule
+ operator: Exists
+ - key: "cloud.google.com/gke-spot"
+ value: "true"
+ effect: NoSchedule
+ operator: Equal
+ - key: kubernetes.azure.com/scalesetpriority
+ value: spot
+ effect: NoSchedule
+ operator: Equal
+ nats:
+ image: nats:2.10.12-alpine3.19
+ advertise: false
+ jetstream:
+ enabled: true
+ memStorage:
+ enabled: true
+ size: 1Gi
+ fileStorage:
+ enabled: true
+ storageDirectory: /data
+ size: 10Gi
+ accessModes:
+ - ReadWriteOnce
+ logging:
+ debug: true
+ natsbox:
+ enabled: false
+ exporter:
+ enabled: true
+ image:
+ tag: "0.14.0"
+ reloader:
+ enabled: true
+ image:
+ tag: "0.14.1"
+ cluster:
+ enabled: true
+ replicas: 3
+ noAdvertise: true
+ websocket:
+ enabled: true
+ port: 443
+ noTLS: true
+ sameOrigin: false
+ allowedOrigins: []
+ auth:
+ enabled: true
+ resolver:
+ type: memory
+ configMap:
+ name: nats-accounts
+ key: resolver.conf
+
+#############################
+# Settings corresponding to the tfy-build server
+tfy-build:
+ enabled: true
+ truefoundryWorkflows:
+ tolerations:
+ - key: class.truefoundry.io/control-plane
+ effect: NoSchedule
+ operator: Exists
+ - key: "cloud.google.com/gke-spot"
+ value: "true"
+ effect: NoSchedule
+ operator: Equal
+ - key: kubernetes.azure.com/scalesetpriority
+ value: spot
+ effect: NoSchedule
+ operator: Equal
+ tfy-buildkitd-service:
+ enabled: true
+ tolerations:
+ - key: class.truefoundry.io/control-plane
+ effect: NoSchedule
+ operator: Exists
+ - key: "cloud.google.com/gke-spot"
+ value: "true"
+ effect: NoSchedule
+ operator: Equal
+ - key: kubernetes.azure.com/scalesetpriority
+ value: spot
+ effect: NoSchedule
+ operator: Equal
+
+#############################
+# Settings corresponding to the llm-gateway
+llm-gateway:
+ enabled: false
+ replicaCount: 1
+ env: {}
+ tolerations:
+ - key: class.truefoundry.io/control-plane
+ effect: NoSchedule
+ operator: Exists
+ - key: "cloud.google.com/gke-spot"
+ value: "true"
+ effect: NoSchedule
+ operator: Equal
+ - key: kubernetes.azure.com/scalesetpriority
+ value: spot
+ effect: NoSchedule
+ operator: Equal
+
+#############################
+# To further configure the local postgres installation use the following section.
+# During cleanup, make sure to remove any stray pvc that might be created.
+postgresql:
+ auth:
+ existingSecret: "truefoundry-postgresql-auth-secret"
+ database: "truefoundry"
+ primary:
+ tolerations:
+ - key: class.truefoundry.io/control-plane
+ effect: NoSchedule
+ operator: Exists
+ - key: "cloud.google.com/gke-spot"
+ value: "true"
+ effect: NoSchedule
+ operator: Equal
+ - key: kubernetes.azure.com/scalesetpriority
+ value: spot
+ effect: NoSchedule
+ operator: Equal
+
+#############################
+# Settings specific to tfy-controller.
+tfy-controller:
+ enabled: true
+ tolerations:
+ - key: class.truefoundry.io/control-plane
+ effect: NoSchedule
+ operator: Exists
+ - key: "cloud.google.com/gke-spot"
+ value: "true"
+ effect: NoSchedule
+ operator: Equal
+ - key: kubernetes.azure.com/scalesetpriority
+ value: spot
+ effect: NoSchedule
+ operator: Equal