Skip to content

Commit 0fa12d4

Browse files
authored
Merge pull request #9 from NetApp/feature/helm-v4
feat(helm): add Neo 4.x Helm chart with microservice architecture
2 parents 645d2e5 + f7ad44d commit 0fa12d4

28 files changed

Lines changed: 1754 additions & 420 deletions

charts/netapp-neo/Chart.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v2
2+
name: netapp-neo
3+
description: NetApp Neo v4.x — context lake microservice architecture for AI services via MCP service
4+
type: application
5+
version: 26.3.1
6+
appVersion: "4.0.3p7"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
NetApp Neo {{ .Chart.AppVersion }} has been deployed!
2+
3+
Services:
4+
- API: {{ include "netapp-neo.fullname" . }}-api:{{ .Values.api.service.port }}
5+
- Worker: {{ include "netapp-neo.fullname" . }}-worker:{{ .Values.worker.service.port }}
6+
- Extractor: {{ include "netapp-neo.fullname" . }}-extractor:{{ .Values.extractor.service.port }}
7+
- NER: {{ include "netapp-neo.fullname" . }}-ner:{{ .Values.ner.service.port }}
8+
- UI: {{ include "netapp-neo.fullname" . }}-ui:{{ .Values.ui.service.port }}
9+
{{- if .Values.postgresql.enabled }}
10+
- PostgreSQL: {{ include "netapp-neo.fullname" . }}-postgres:{{ .Values.postgresql.service.port }}
11+
{{- else }}
12+
- PostgreSQL: external ({{ .Values.postgresql.externalDatabaseUrl }})
13+
{{- end }}
14+
15+
{{- if .Values.api.ingress.enabled }}
16+
17+
API Ingress:
18+
{{- if .Values.api.ingress.host }}
19+
URL: http{{ if .Values.api.ingress.tls }}s{{ end }}://{{ .Values.api.ingress.host }}
20+
{{- else }}
21+
URL: configured without a host (catch-all)
22+
{{- end }}
23+
{{- end }}
24+
25+
{{- if .Values.ui.ingress.enabled }}
26+
27+
UI Ingress:
28+
{{- if .Values.ui.ingress.host }}
29+
URL: http{{ if .Values.ui.ingress.tls }}s{{ end }}://{{ .Values.ui.ingress.host }}
30+
{{- else }}
31+
URL: configured without a host (catch-all)
32+
{{- end }}
33+
{{- end }}
34+
35+
To access the API locally:
36+
kubectl -n {{ .Release.Namespace}} port-forward svc/{{ include "netapp-neo.fullname" . }}-api {{ .Values.api.service.port }}:{{ .Values.api.service.port }}
37+
38+
To access the UI locally:
39+
kubectl -n {{ .Release.Namespace}} port-forward svc/{{ include "netapp-neo.fullname" . }}-ui 8080:{{ .Values.ui.service.port }}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{{/*
2+
Chart name, truncated to 63 chars.
3+
*/}}
4+
{{- define "netapp-neo.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
6+
{{- end -}}
7+
8+
{{/*
9+
Fully qualified app name: <release>-<chart>
10+
*/}}
11+
{{- define "netapp-neo.fullname" -}}
12+
{{- if .Values.fullnameOverride -}}
13+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
14+
{{- else -}}
15+
{{- printf "%s-%s" .Release.Name (include "netapp-neo.name" .) | trunc 63 | trimSuffix "-" -}}
16+
{{- end -}}
17+
{{- end -}}
18+
19+
{{/*
20+
Component name: <fullname>-<component>
21+
*/}}
22+
{{- define "netapp-neo.componentName" -}}
23+
{{- printf "%s-%s" (include "netapp-neo.fullname" .) . | trunc 63 | trimSuffix "-" -}}
24+
{{- end -}}
25+
26+
{{/*
27+
Common labels
28+
*/}}
29+
{{- define "netapp-neo.labels" -}}
30+
app.kubernetes.io/name: {{ include "netapp-neo.name" . }}
31+
app.kubernetes.io/instance: {{ .Release.Name }}
32+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
33+
app.kubernetes.io/managed-by: {{ .Release.Service }}
34+
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
35+
{{- end -}}
36+
37+
{{/*
38+
Selector labels for a component.
39+
Usage: include "netapp-neo.selectorLabels" (dict "context" . "component" "api")
40+
*/}}
41+
{{- define "netapp-neo.selectorLabels" -}}
42+
app.kubernetes.io/name: {{ include "netapp-neo.name" .context }}
43+
app.kubernetes.io/instance: {{ .context.Release.Name }}
44+
app.kubernetes.io/component: {{ .component }}
45+
{{- end -}}
46+
47+
{{/*
48+
Construct DATABASE_URL.
49+
When postgresql.enabled, builds from auth creds and service name.
50+
Otherwise uses postgresql.externalDatabaseUrl.
51+
*/}}
52+
{{- define "netapp-neo.databaseUrl" -}}
53+
{{- if .Values.postgresql.enabled -}}
54+
postgresql://{{ .Values.postgresql.auth.username | urlquery }}:{{ .Values.postgresql.auth.password | urlquery }}@{{ include "netapp-neo.fullname" . }}-postgres:{{ .Values.postgresql.service.port }}/{{ .Values.postgresql.auth.database | urlquery }}
55+
{{- else -}}
56+
{{ .Values.postgresql.externalDatabaseUrl }}
57+
{{- end -}}
58+
{{- end -}}
59+
60+
{{/*
61+
Inter-service URL helpers.
62+
These construct cluster-internal URLs so users never configure them manually.
63+
*/}}
64+
{{- define "netapp-neo.apiUrl" -}}
65+
http://{{ include "netapp-neo.fullname" . }}-api:{{ .Values.api.service.port }}
66+
{{- end -}}
67+
68+
{{- define "netapp-neo.workerUrl" -}}
69+
http://{{ include "netapp-neo.fullname" . }}-worker:{{ .Values.worker.service.port }}
70+
{{- end -}}
71+
72+
{{- define "netapp-neo.extractorUrl" -}}
73+
http://{{ include "netapp-neo.fullname" . }}-extractor:{{ .Values.extractor.service.port }}
74+
{{- end -}}
75+
76+
{{- define "netapp-neo.nerUrl" -}}
77+
http://{{ include "netapp-neo.fullname" . }}-ner:{{ .Values.ner.service.port }}
78+
{{- end -}}
79+
80+
{{/*
81+
Wait-for-db init container (reusable).
82+
Usage: include "netapp-neo.waitForDb" .
83+
Only useful when postgresql.enabled is true.
84+
*/}}
85+
{{- define "netapp-neo.waitForDb" -}}
86+
- name: wait-for-db
87+
image: "{{ .Values.postgresql.image.repository }}:{{ .Values.postgresql.image.tag }}"
88+
command:
89+
- sh
90+
- -c
91+
- |
92+
until pg_isready \
93+
-h {{ include "netapp-neo.fullname" . }}-postgres \
94+
-p {{ .Values.postgresql.service.port }} \
95+
-U {{ .Values.postgresql.auth.username }} \
96+
-d {{ .Values.postgresql.auth.database }}; do
97+
echo "Waiting for PostgreSQL…"
98+
sleep 2
99+
done
100+
echo "PostgreSQL is ready!"
101+
env:
102+
- name: PGPASSWORD
103+
valueFrom:
104+
secretKeyRef:
105+
name: {{ include "netapp-neo.fullname" . }}-db
106+
key: POSTGRES_PASSWORD
107+
{{- end -}}
108+
109+
{{/*
110+
Resolve image tag — falls back to Chart.AppVersion when tag is empty.
111+
Usage: include "netapp-neo.imageTag" (dict "imageTag" .Values.api.image.tag "appVersion" .Chart.AppVersion)
112+
*/}}
113+
{{- define "netapp-neo.imageTag" -}}
114+
{{- default .appVersion .imageTag -}}
115+
{{- end -}}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: {{ include "netapp-neo.fullname" . }}-api
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
{{- include "netapp-neo.labels" . | nindent 4 }}
8+
app.kubernetes.io/component: api
9+
data:
10+
WORKER_SERVICE_URL: {{ include "netapp-neo.workerUrl" . | quote }}
11+
NER_SERVICE_URL: {{ include "netapp-neo.nerUrl" . | quote }}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "netapp-neo.fullname" . }}-api
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
{{- include "netapp-neo.labels" . | nindent 4 }}
8+
app.kubernetes.io/component: api
9+
spec:
10+
replicas: {{ .Values.api.replicaCount }}
11+
selector:
12+
matchLabels:
13+
{{- include "netapp-neo.selectorLabels" (dict "context" . "component" "api") | nindent 6 }}
14+
template:
15+
metadata:
16+
labels:
17+
{{- include "netapp-neo.selectorLabels" (dict "context" . "component" "api") | nindent 8 }}
18+
spec:
19+
{{- with .Values.imagePullSecrets }}
20+
imagePullSecrets:
21+
{{- toYaml . | nindent 8 }}
22+
{{- end }}
23+
securityContext:
24+
runAsUser: 1000
25+
runAsGroup: 1000
26+
fsGroup: 1000
27+
{{- if .Values.postgresql.enabled }}
28+
initContainers:
29+
{{- include "netapp-neo.waitForDb" . | nindent 8 }}
30+
{{- end }}
31+
containers:
32+
- name: api
33+
image: "{{ .Values.api.image.repository }}:{{ include "netapp-neo.imageTag" (dict "imageTag" .Values.api.image.tag "appVersion" .Chart.AppVersion) }}"
34+
imagePullPolicy: {{ .Values.api.image.pullPolicy }}
35+
ports:
36+
- name: http
37+
containerPort: {{ .Values.api.service.port }}
38+
protocol: TCP
39+
# envFrom:
40+
# - configMapRef:
41+
# name: {{ include "netapp-neo.fullname" . }}-api
42+
env:
43+
- name: DATABASE_URL
44+
valueFrom:
45+
secretKeyRef:
46+
name: {{ include "netapp-neo.fullname" . }}-db
47+
key: DATABASE_URL
48+
{{- with .Values.api.resources }}
49+
resources:
50+
{{- toYaml . | nindent 12 }}
51+
{{- end }}
52+
livenessProbe:
53+
httpGet:
54+
path: /health
55+
port: http
56+
initialDelaySeconds: 10
57+
periodSeconds: 30
58+
timeoutSeconds: 10
59+
failureThreshold: 3
60+
readinessProbe:
61+
httpGet:
62+
path: /health
63+
port: http
64+
initialDelaySeconds: 10
65+
periodSeconds: 10
66+
timeoutSeconds: 10
67+
failureThreshold: 3
68+
restartPolicy: Always
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{{- $ing := .Values.api.ingress | default dict -}}
2+
{{- if $ing.enabled }}
3+
apiVersion: networking.k8s.io/v1
4+
kind: Ingress
5+
metadata:
6+
name: {{ include "netapp-neo.fullname" . }}-api
7+
namespace: {{ .Release.Namespace }}
8+
labels:
9+
{{- include "netapp-neo.labels" . | nindent 4 }}
10+
app.kubernetes.io/component: api
11+
{{- with $ing.annotations }}
12+
annotations:
13+
{{- toYaml . | nindent 4 }}
14+
{{- end }}
15+
spec:
16+
{{- with $ing.className }}
17+
ingressClassName: {{ . }}
18+
{{- end }}
19+
{{- with $ing.tls }}
20+
tls:
21+
{{- toYaml . | nindent 4 }}
22+
{{- end }}
23+
rules:
24+
{{- if $ing.host }}
25+
- host: {{ $ing.host | quote }}
26+
http:
27+
paths:
28+
- path: {{ $ing.path | default "/" }}
29+
pathType: {{ $ing.pathType | default "Prefix" }}
30+
backend:
31+
service:
32+
name: {{ include "netapp-neo.fullname" . }}-api
33+
port:
34+
number: {{ .Values.api.service.port | int }}
35+
{{- else }}
36+
- http:
37+
paths:
38+
- path: {{ $ing.path | default "/" }}
39+
pathType: {{ $ing.pathType | default "Prefix" }}
40+
backend:
41+
service:
42+
name: {{ include "netapp-neo.fullname" . }}-api
43+
port:
44+
number: {{ .Values.api.service.port | int }}
45+
{{- end }}
46+
{{- end }}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: {{ include "netapp-neo.fullname" . }}-api
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
{{- include "netapp-neo.labels" . | nindent 4 }}
8+
app.kubernetes.io/component: api
9+
spec:
10+
type: {{ .Values.api.service.type }}
11+
sessionAffinity: {{ .Values.api.service.sessionAffinity }}
12+
ports:
13+
- port: {{ .Values.api.service.port }}
14+
targetPort: http
15+
protocol: TCP
16+
name: http
17+
selector:
18+
{{- include "netapp-neo.selectorLabels" (dict "context" . "component" "api") | nindent 4 }}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: {{ include "netapp-neo.fullname" . }}-extractor
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
{{- include "netapp-neo.labels" . | nindent 4 }}
8+
app.kubernetes.io/component: extractor
9+
data:
10+
EXTRACTOR_LOG_LEVEL: {{ .Values.extractor.env.EXTRACTOR_LOG_LEVEL | quote }}
11+
EXTRACTOR_DEFAULT_PIPELINE: {{ .Values.extractor.env.EXTRACTOR_DEFAULT_PIPELINE | quote }}
12+
EXTRACTOR_MOUNT_TTL: {{ .Values.extractor.env.EXTRACTOR_MOUNT_TTL | quote }}
13+
EXTRACTOR_FORCE_CPU: {{ .Values.extractor.env.EXTRACTOR_FORCE_CPU | quote }}
14+
VLM_MODEL: {{ .Values.extractor.env.VLM_MODEL | quote }}
15+
VLM_API_URL: {{ .Values.extractor.env.VLM_API_URL | quote }}
16+
VLM_API_MODEL: {{ .Values.extractor.env.VLM_API_MODEL | quote }}
17+
OPENAI_MODEL: {{ .Values.extractor.env.OPENAI_MODEL | quote }}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "netapp-neo.fullname" . }}-extractor
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
{{- include "netapp-neo.labels" . | nindent 4 }}
8+
app.kubernetes.io/component: extractor
9+
spec:
10+
replicas: {{ .Values.extractor.replicaCount }}
11+
selector:
12+
matchLabels:
13+
{{- include "netapp-neo.selectorLabels" (dict "context" . "component" "extractor") | nindent 6 }}
14+
template:
15+
metadata:
16+
labels:
17+
{{- include "netapp-neo.selectorLabels" (dict "context" . "component" "extractor") | nindent 8 }}
18+
spec:
19+
{{- with .Values.imagePullSecrets }}
20+
imagePullSecrets:
21+
{{- toYaml . | nindent 8 }}
22+
{{- end }}
23+
{{- if .Values.postgresql.enabled }}
24+
initContainers:
25+
{{- include "netapp-neo.waitForDb" . | nindent 8 }}
26+
{{- end }}
27+
containers:
28+
- name: extractor
29+
image: "{{ .Values.extractor.image.repository }}:{{ include "netapp-neo.imageTag" (dict "imageTag" .Values.extractor.image.tag "appVersion" .Chart.AppVersion) }}"
30+
imagePullPolicy: {{ .Values.extractor.image.pullPolicy }}
31+
ports:
32+
- name: http
33+
containerPort: {{ .Values.extractor.service.port }}
34+
protocol: TCP
35+
envFrom:
36+
- configMapRef:
37+
name: {{ include "netapp-neo.fullname" . }}-extractor
38+
env:
39+
- name: DATABASE_URL
40+
valueFrom:
41+
secretKeyRef:
42+
name: {{ include "netapp-neo.fullname" . }}-db
43+
key: DATABASE_URL
44+
securityContext:
45+
privileged: true
46+
{{- with .Values.extractor.resources }}
47+
resources:
48+
{{- toYaml . | nindent 12 }}
49+
{{- end }}
50+
livenessProbe:
51+
httpGet:
52+
path: /health
53+
port: http
54+
initialDelaySeconds: 30
55+
periodSeconds: 30
56+
timeoutSeconds: 10
57+
failureThreshold: 3
58+
readinessProbe:
59+
httpGet:
60+
path: /health
61+
port: http
62+
initialDelaySeconds: 30
63+
periodSeconds: 10
64+
timeoutSeconds: 10
65+
failureThreshold: 3
66+
restartPolicy: Always

0 commit comments

Comments
 (0)