Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions braintrust/templates/virtualservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{- if .Values.virtualService.enabled }}
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: {{ .Values.virtualService.name | default (printf "%s-vs" .Values.api.name) }}
namespace: {{ include "braintrust.namespace" . }}
{{- with (merge .Values.global.labels .Values.virtualService.labels) }}
labels:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.virtualService.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.virtualService.gateways }}
gateways:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.virtualService.hosts }}
hosts:
{{- toYaml . | nindent 4 }}
{{- end }}
http:
{{- range .Values.virtualService.http }}
- {{- toYaml . | nindent 6 }}
{{- end }}
{{- end }}
252 changes: 252 additions & 0 deletions braintrust/tests/virtualservice_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
suite: test VirtualService template
templates:
- virtualservice.yaml
tests:
- it: should not render when virtualService is disabled
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: false
asserts:
- hasDocuments:
count: 0

- it: should render VirtualService when enabled
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
asserts:
- hasDocuments:
count: 1
- isKind:
of: VirtualService
- isAPIVersion:
of: networking.istio.io/v1

- it: should use default name when not provided
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
api.name: "braintrust-api"
asserts:
- equal:
path: metadata.name
value: braintrust-api-vs

- it: should use custom name when provided
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
virtualService.name: "custom-virtualservice"
asserts:
- equal:
path: metadata.name
value: custom-virtualservice

- it: should use correct namespace from helper when createNamespace is false
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
global.namespace: "custom-ns"
global.createNamespace: false
release:
namespace: "release-namespace"
asserts:
- equal:
path: metadata.namespace
value: release-namespace

- it: should use global namespace when createNamespace is true
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
global.namespace: "custom-ns"
global.createNamespace: true
release:
namespace: "release-namespace"
asserts:
- equal:
path: metadata.namespace
value: custom-ns

- it: should merge global and virtualService labels
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
global.labels.environment: "production"
global.labels.team: "platform"
virtualService.labels.component: "virtualservice"
asserts:
- equal:
path: metadata.labels.environment
value: production
- equal:
path: metadata.labels.team
value: platform
- equal:
path: metadata.labels.component
value: virtualservice

- it: should not bleed labels from other components
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
global.labels.shared: "global-label"
virtualService.labels.vs-specific: "vs-label"
api.labels.api-specific: "api-label"
brainstore.reader.labels.reader-specific: "reader-label"
asserts:
- equal:
path: metadata.labels.shared
value: global-label
- equal:
path: metadata.labels.vs-specific
value: vs-label
- isNull:
path: metadata.labels.api-specific
- isNull:
path: metadata.labels.reader-specific

- it: should include annotations when provided
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
virtualService.annotations:
custom-annotation: "value"
another-annotation: "another-value"
asserts:
- equal:
path: metadata.annotations["custom-annotation"]
value: value
- equal:
path: metadata.annotations["another-annotation"]
value: another-value

- it: should configure gateways correctly
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
virtualService.gateways:
- "istio-gateway"
- "istio-ingress/asm-gateway"
asserts:
- equal:
path: spec.gateways[0]
value: istio-gateway
- equal:
path: spec.gateways[1]
value: istio-ingress/asm-gateway

- it: should configure hosts correctly
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
virtualService.hosts:
- "braintrust.example.com"
- "api.braintrust.com"
asserts:
- equal:
path: spec.hosts[0]
value: braintrust.example.com
- equal:
path: spec.hosts[1]
value: api.braintrust.com

- it: should configure HTTP routes with match and destination
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
virtualService.http:
- match:
- uri:
prefix: "/"
route:
- destination:
host: "braintrust-api"
port:
number: 8000
asserts:
- equal:
path: spec.http[0].match[0].uri.prefix
value: /
- equal:
path: spec.http[0].route[0].destination.host
value: braintrust-api
- equal:
path: spec.http[0].route[0].destination.port.number
value: 8000

- it: should support multiple HTTP routes
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
virtualService.http:
- match:
- uri:
prefix: "/api"
route:
- destination:
host: "braintrust-api"
port:
number: 8000
- match:
- uri:
prefix: "/health"
route:
- destination:
host: "braintrust-api"
port:
number: 8000
asserts:
- equal:
path: spec.http[0].match[0].uri.prefix
value: /api
- equal:
path: spec.http[1].match[0].uri.prefix
value: /health

- it: should support complex HTTP routing with headers and methods
values:
- __fixtures__/base-values.yaml
set:
virtualService.enabled: true
virtualService.http:
- match:
- uri:
prefix: "/api"
headers:
api-version:
exact: "v2"
method:
exact: "GET"
route:
- destination:
host: "braintrust-api"
port:
number: 8000
weight: 100
asserts:
- equal:
path: spec.http[0].match[0].uri.prefix
value: /api
- equal:
path: spec.http[0].match[0].headers.api-version.exact
value: v2
- equal:
path: spec.http[0].match[0].method.exact
value: GET
- equal:
path: spec.http[0].route[0].weight
value: 100
26 changes: 26 additions & 0 deletions braintrust/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,29 @@ azureKeyVaultDriver:
- keyVaultSecretName: "azure-storage-connection-string"
keyVaultSecretType: "secret"
kubernetesSecretKey: "AZURE_STORAGE_CONNECTION_STRING"

# Istio VirtualService configuration (optional)
# Enable this to create an Istio VirtualService for the API
virtualService:
enabled: false
name: "" # If empty, defaults to "<api.name>-vs"
labels: {}
annotations: {}
# List of gateway names (can include namespace, e.g., "istio-ingress/asm-gateway")
gateways:
- "istio-gateway"
# List of hosts/domains
hosts:
- "braintrust.example.com"
# HTTP routing rules
# The destination host will use api.service.name (or api.name if service.name is empty)
# The destination port will use api.service.port (default: 8000)
http:
- match:
- uri:
prefix: "/"
route:
- destination:
host: "braintrust-api" # Should match api.service.name or api.name
port:
number: 8000 # Should match api.service.port