first commit
This commit is contained in:
24
helm-charts/bifrost/.helmignore
Normal file
24
helm-charts/bifrost/.helmignore
Normal file
@@ -0,0 +1,24 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
|
||||
19
helm-charts/bifrost/Chart.yaml
Normal file
19
helm-charts/bifrost/Chart.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: v2
|
||||
name: bifrost
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
type: application
|
||||
version: 2.1.5
|
||||
appVersion: "1.5.0-prerelease4"
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
- openai
|
||||
- anthropic
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
maintainers:
|
||||
- name: Bifrost Team
|
||||
email: support@getbifrost.ai
|
||||
icon: https://www.getbifrost.ai/favicon.png
|
||||
741
helm-charts/bifrost/README.md
Normal file
741
helm-charts/bifrost/README.md
Normal file
@@ -0,0 +1,741 @@
|
||||
# Bifrost Helm Charts
|
||||
|
||||
[](https://artifacthub.io/packages/helm/bifrost/bifrost)
|
||||
|
||||
Official Helm charts for deploying [Bifrost](https://github.com/maximhq/bifrost) - a high-performance AI gateway with unified interface for multiple providers.
|
||||
|
||||
**Latest Version:** 2.1.4
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2.1.3
|
||||
|
||||
- For `bifrost.cluster.discovery.type` set to `consul`, `etcd`, or `udp`, set `bifrost.cluster.discovery.serviceName` explicitly during upgrade.
|
||||
|
||||
### v2.1.2
|
||||
|
||||
- Removed `encryption_key` requirement — field is now optional; Bifrost will operate without encryption when omitted
|
||||
|
||||
### v2.1.1
|
||||
|
||||
- Made `bifrost.governance.virtualKeys[].value` optional — template no longer fails when the field is omitted, allowing the backend to auto-generate the virtual key value
|
||||
- When `value` is absent, the rendered `config.json` omits the field entirely (consistent with other optional VK fields)
|
||||
|
||||
### v2.1.0-prerelease2 (prerelease)
|
||||
|
||||
- Synced helm `values.schema.json` with transport `config.schema.json` — fixed virtual key and budget drift:
|
||||
- Removed `required: [mcp_client_id]` constraint on `virtualKeys[].mcp_configs[]` items — canonical schema accepts either `mcp_client_id` (DB form) or `mcp_client_name` (config-file form, resolved to ID at startup)
|
||||
- Added `mcp_client_name` as an allowed property on `virtualKeys[].mcp_configs[]` items
|
||||
- Added `calendar_aligned` (boolean) on `virtualKeys[]` — field now lives on the virtual key, applies uniformly to all budgets under it
|
||||
- Removed stale `budget_id` from `virtualKeys[]` — `TableVirtualKey` has no `BudgetID`; budgets link via foreign key from the budget table
|
||||
- Removed stale `calendar_aligned` from `budgets[]` — moved to virtual key level
|
||||
|
||||
### v2.0.17
|
||||
|
||||
- Added object storage support (S3/GCS) for offloading log payloads from the database
|
||||
- Added `storage.logsStore.objectStorage` configuration with S3 and GCS backend support
|
||||
- Added object storage credential injection from Kubernetes secrets (`existingSecret`)
|
||||
- Added `object_storage` schema to `config.schema.json` under `logs_store`
|
||||
- Updated deployment and stateful templates with object storage secret env vars
|
||||
|
||||
### v2.0.16
|
||||
|
||||
- Fixed disabled custom plugins being completely removed from rendered config.json instead of being kept with `enabled: false`
|
||||
|
||||
### v2.0.15
|
||||
|
||||
- Synced helm schema with transport `config.schema.json` — added missing properties:
|
||||
- `client.mcpDisableAutoToolInject` — disable automatic MCP tool injection
|
||||
- `governance.budgets[].calendar_aligned` — snap budget resets to calendar boundaries
|
||||
- `governance.pricingOverrides` — scoped pricing overrides for the model catalog
|
||||
- `mcp.clientConfigs[].allowedExtraHeaders` — header allowlist per MCP client
|
||||
- `mcp.clientConfigs[].allowOnAllVirtualKeys` — make MCP server accessible to all virtual keys
|
||||
- `mcp.toolManagerConfig.disableAutoToolInject` — disable auto tool injection at manager level
|
||||
- `networkConfig.beta_header_overrides` — override Anthropic beta header support per provider
|
||||
- `websocket` — full WebSocket gateway tuning (connections, pool, transcript buffer)
|
||||
- Fixed SSE `connectionString` not being rendered in `_helpers.tpl` for MCP clients
|
||||
- Added template rendering for all new properties in `_helpers.tpl`
|
||||
|
||||
### v2.0.14
|
||||
|
||||
- Added `placement` and `order` fields to custom plugin schema and template rendering
|
||||
- Added plugin property completeness check to `validate-helm-schema.sh`
|
||||
- Added custom plugin placement/order rendering tests to `validate-helm-templates.sh`
|
||||
- Added `PluginConfig` struct validation to `validate-go-config-fields.sh`
|
||||
|
||||
### v2.0.13
|
||||
|
||||
- Added missing client config properties: `asyncJobResultTTL`, `requiredHeaders`, `loggingHeaders`, `allowedHeaders`, `mcpAgentDepth`, `mcpToolExecutionTimeout`, `mcpCodeModeBindingLevel`, `mcpToolSyncInterval`, `hideDeletedVirtualKeysInFilters`
|
||||
- Added MCP new fields: top-level `toolSyncInterval`, per-client `clientId`, `isCodeModeClient`, `toolSyncInterval`, `isPingAvailable`, `toolPricing`, and `codeModeBindingLevel` in tool manager config
|
||||
- Added governance `modelConfigs` and `providers` top-level properties
|
||||
- Added cluster `region` property
|
||||
- Added guardrail provider `timeout` field (was missing from schema and template rendering)
|
||||
- Fixed `isPingAvailable` rendering bug in `_helpers.tpl` (was using wrong key name)
|
||||
- Added `is_ping_available` and `tool_pricing` to `config.schema.json` MCP client config
|
||||
- Added new CI script `validate-go-config-fields.sh` for Go struct-to-schema drift detection
|
||||
- Expanded all 3 existing CI validation scripts with Gap 1-8 property coverage
|
||||
|
||||
### v2.0.12
|
||||
|
||||
- Fixed health probe paths to use `/health` instead of `/metrics`
|
||||
|
||||
### v2.0.11
|
||||
|
||||
- Bumped appVersion to 1.4.11
|
||||
|
||||
### v2.0.10
|
||||
|
||||
- Added missing plugin config properties from Go implementations:
|
||||
- governance: `required_headers`, `is_enterprise`
|
||||
- logging: `disable_content_logging`, `logging_headers`
|
||||
- otel: `headers`, `tls_ca_cert`, `insecure`
|
||||
- telemetry: `custom_labels`
|
||||
|
||||
### v2.0.9
|
||||
|
||||
- Bumped appVersion to 1.4.8
|
||||
|
||||
### v2.0.8
|
||||
|
||||
- Added comprehensive config field coverage for all `config.schema.json` fields
|
||||
- Added Pinecone vector store support (external only) with secret injection
|
||||
- Added governance routing rules template support
|
||||
- Added OTEL metrics fields (metrics_enabled, metrics_endpoint, metrics_push_interval)
|
||||
- Added advanced Redis connection pool fields (pool_size, timeouts, idle conns, etc.)
|
||||
- Added Weaviate timeout and className fields
|
||||
- Expanded values.yaml with commented examples for all provider types (Azure, Vertex, Bedrock), network config, concurrency, proxy config, and governance entities
|
||||
- Added helm config field validation CI test (246 assertions covering all config.schema.json fields)
|
||||
|
||||
### v2.0.7
|
||||
|
||||
- Previous release
|
||||
|
||||
### v2.0.6
|
||||
|
||||
- Fixes MCP client config template to convert camelCase Helm values to snake_case config format
|
||||
|
||||
### v2.0.5
|
||||
|
||||
- Fixes config field validation parity
|
||||
|
||||
### v2.0.2
|
||||
|
||||
- Added Qdrant vector store support with deployment, service, and PVC templates
|
||||
- Added headless service template for StatefulSet DNS resolution
|
||||
- Fixed gitignore pattern that was excluding template files from version control
|
||||
|
||||
### v2.0.1
|
||||
|
||||
- Added missing StatefulSet template for SQLite with persistence mode
|
||||
- Added headless service for StatefulSet DNS resolution
|
||||
- v2.0.0 documented StatefulSet support but the template was not included - this release fixes that
|
||||
|
||||
### v2.0.0 (Breaking Change)
|
||||
|
||||
#### StatefulSet for SQLite with Persistence
|
||||
|
||||
This release fixes the multi-attach volume error when running multiple replicas with SQLite storage mode.
|
||||
|
||||
#### What Changed
|
||||
|
||||
- When using `storage.mode: sqlite` with `storage.persistence.enabled: true`, Bifrost now deploys as a **StatefulSet** instead of a Deployment
|
||||
- Each pod gets its own dedicated PersistentVolumeClaim (e.g., `data-bifrost-0`, `data-bifrost-1`, `data-bifrost-2`)
|
||||
- A headless service is created for StatefulSet DNS resolution
|
||||
- HorizontalPodAutoscaler now correctly references StatefulSet or Deployment based on storage configuration
|
||||
|
||||
#### Who Is Affected
|
||||
|
||||
- Users running SQLite mode with persistence enabled and multiple replicas
|
||||
- Users upgrading existing SQLite deployments need to migrate (see below)
|
||||
|
||||
#### Who Is NOT Affected
|
||||
|
||||
- Users running PostgreSQL mode (`storage.mode: postgres`) - no changes, still uses Deployment
|
||||
- Users running SQLite without persistence (`storage.persistence.enabled: false`)
|
||||
- Users running SQLite with an existing PVC claim (`storage.persistence.existingClaim`)
|
||||
|
||||
#### Migration Guide for Existing SQLite Deployments
|
||||
|
||||
Since Kubernetes doesn't allow in-place conversion from Deployment to StatefulSet, you need to:
|
||||
|
||||
1. Back up your data (if needed)
|
||||
2. Uninstall the existing release: `helm uninstall bifrost`
|
||||
3. Delete the old PVC: `kubectl delete pvc bifrost-data`
|
||||
4. Install with the new chart version: `helm install bifrost bifrost/bifrost --set image.tag=<latest-image>`
|
||||
|
||||
**Note:** For production high-availability setups, we recommend using PostgreSQL mode which scales horizontally without these concerns.
|
||||
|
||||
### v1.7.0
|
||||
|
||||
- Previous stable release with Deployment-based architecture for all storage modes
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Add the Bifrost Helm repository
|
||||
helm repo add bifrost https://maximhq.github.io/bifrost/helm-charts
|
||||
|
||||
# Update your local Helm chart repository cache
|
||||
helm repo update
|
||||
|
||||
# Install Bifrost with default configuration (SQLite storage)
|
||||
helm install bifrost bifrost/bifrost --set image.tag=v1.4.3
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes 1.23+
|
||||
- Helm 3.2.0+
|
||||
- PV provisioner support in the underlying infrastructure (for persistent storage)
|
||||
|
||||
## Installation
|
||||
|
||||
### From Helm Repository (Recommended)
|
||||
|
||||
```bash
|
||||
# Add repository
|
||||
helm repo add bifrost https://maximhq.github.io/bifrost/helm-charts
|
||||
helm repo update
|
||||
|
||||
# Install with default values
|
||||
helm install bifrost bifrost/bifrost --set image.tag=v1.4.3
|
||||
|
||||
# Or install with custom values
|
||||
helm install bifrost bifrost/bifrost -f my-values.yaml
|
||||
```
|
||||
|
||||
### From Source
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/maximhq/bifrost.git
|
||||
cd bifrost/helm-charts
|
||||
|
||||
# Install from local chart
|
||||
helm install bifrost ./bifrost --set image.tag=v1.5.2
|
||||
```
|
||||
|
||||
### Interactive Installation
|
||||
|
||||
Use the included installation script for guided setup:
|
||||
|
||||
```bash
|
||||
cd bifrost/helm-charts/bifrost
|
||||
./scripts/install.sh
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Image Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `image.repository` | Container image repository | `docker.io/maximhq/bifrost` |
|
||||
| `image.tag` | Container image tag (required) | `""` |
|
||||
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
|
||||
|
||||
> **Important:** You must specify the `image.tag`. See available tags at [Docker Hub](https://hub.docker.com/r/maximhq/bifrost/tags).
|
||||
|
||||
### Enterprise Private Registry
|
||||
|
||||
For enterprise customers with private container registries, simply override the `image.repository` with your full registry URL:
|
||||
|
||||
```yaml
|
||||
# Google Artifact Registry
|
||||
image:
|
||||
repository: us-west1-docker.pkg.dev/bifrost-enterprise/your-org/bifrost
|
||||
tag: v1.5.0
|
||||
|
||||
# AWS ECR
|
||||
image:
|
||||
repository: 123456789.dkr.ecr.us-east-1.amazonaws.com/bifrost
|
||||
tag: v1.5.0
|
||||
|
||||
# Azure Container Registry
|
||||
image:
|
||||
repository: yourregistry.azurecr.io/bifrost
|
||||
tag: v1.5.0
|
||||
|
||||
# Self-hosted registry
|
||||
image:
|
||||
repository: registry.yourcompany.com/ai/bifrost
|
||||
tag: v1.5.0
|
||||
```
|
||||
|
||||
If your private registry requires authentication, configure `imagePullSecrets`:
|
||||
|
||||
```yaml
|
||||
image:
|
||||
repository: us-west1-docker.pkg.dev/bifrost-enterprise/your-org/bifrost
|
||||
tag: v1.5.0
|
||||
|
||||
imagePullSecrets:
|
||||
- name: my-registry-secret
|
||||
```
|
||||
|
||||
Create the secret beforehand:
|
||||
```bash
|
||||
kubectl create secret docker-registry my-registry-secret \
|
||||
--docker-server=us-west1-docker.pkg.dev \
|
||||
--docker-username=_json_key \
|
||||
--docker-password="$(cat key.json)" \
|
||||
--docker-email=your-email@example.com
|
||||
```
|
||||
|
||||
### Storage Configuration
|
||||
|
||||
Bifrost supports two storage backends (SQLite and PostgreSQL) that can be configured independently for config and logs stores.
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `storage.mode` | Default storage backend (fallback when per-store type not set) | `sqlite` |
|
||||
| `storage.persistence.enabled` | Enable persistent storage for SQLite | `true` |
|
||||
| `storage.persistence.size` | Storage size | `10Gi` |
|
||||
| `storage.configStore.enabled` | Enable configuration store | `true` |
|
||||
| `storage.configStore.type` | Config store backend: `sqlite`, `postgres`, or `""` | `""` (uses `storage.mode`) |
|
||||
| `storage.logsStore.enabled` | Enable logs store | `true` |
|
||||
| `storage.logsStore.type` | Logs store backend: `sqlite`, `postgres`, or `""` | `""` (uses `storage.mode`) |
|
||||
|
||||
#### Mixed Backend Example
|
||||
|
||||
You can use different backends for config and logs stores:
|
||||
|
||||
```yaml
|
||||
storage:
|
||||
mode: sqlite # Default fallback
|
||||
configStore:
|
||||
enabled: true
|
||||
type: sqlite # Config in SQLite (fast, local)
|
||||
logsStore:
|
||||
enabled: true
|
||||
type: postgres # Logs in PostgreSQL (scalable, queryable)
|
||||
|
||||
postgresql:
|
||||
enabled: true
|
||||
# ... PostgreSQL configuration for logs store
|
||||
```
|
||||
|
||||
### PostgreSQL Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `postgresql.enabled` | Deploy PostgreSQL | `false` |
|
||||
| `postgresql.auth.username` | Database username | `bifrost` |
|
||||
| `postgresql.auth.password` | Database password | `bifrost_password` |
|
||||
| `postgresql.auth.database` | Database name | `bifrost` |
|
||||
| `postgresql.external.enabled` | Use external PostgreSQL | `false` |
|
||||
| `postgresql.external.host` | External PostgreSQL host | `""` |
|
||||
|
||||
### Vector Store Configuration (Semantic Caching)
|
||||
|
||||
Bifrost supports multiple vector stores for semantic caching:
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `vectorStore.enabled` | Enable vector store | `false` |
|
||||
| `vectorStore.type` | Vector store type: `none`, `weaviate`, `redis`, `qdrant` | `none` |
|
||||
|
||||
#### Weaviate
|
||||
|
||||
```yaml
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: weaviate
|
||||
weaviate:
|
||||
enabled: true # Deploy Weaviate
|
||||
# Or use external:
|
||||
# external:
|
||||
# enabled: true
|
||||
# host: "weaviate.example.com"
|
||||
```
|
||||
|
||||
#### Redis
|
||||
|
||||
```yaml
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: redis
|
||||
redis:
|
||||
enabled: true # Deploy Redis
|
||||
# Or use external:
|
||||
# external:
|
||||
# enabled: true
|
||||
# host: "redis.example.com"
|
||||
```
|
||||
|
||||
#### Qdrant
|
||||
|
||||
```yaml
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: qdrant
|
||||
qdrant:
|
||||
enabled: true # Deploy Qdrant
|
||||
# Or use external:
|
||||
# external:
|
||||
# enabled: true
|
||||
# host: "qdrant.example.com"
|
||||
```
|
||||
|
||||
### Bifrost Application Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `bifrost.port` | Application port | `8080` |
|
||||
| `bifrost.host` | Bind address | `0.0.0.0` |
|
||||
| `bifrost.logLevel` | Log level | `info` |
|
||||
| `bifrost.logStyle` | Log format: `json` or `text` | `json` |
|
||||
| `bifrost.encryptionKey` | Encryption key for sensitive data | `""` |
|
||||
|
||||
### Provider Configuration
|
||||
|
||||
Configure AI provider API keys:
|
||||
|
||||
```yaml
|
||||
bifrost:
|
||||
providers:
|
||||
openai:
|
||||
keys:
|
||||
- value: "sk-..."
|
||||
weight: 1
|
||||
anthropic:
|
||||
keys:
|
||||
- value: "sk-ant-..."
|
||||
weight: 1
|
||||
```
|
||||
|
||||
### Plugins Configuration
|
||||
|
||||
| Plugin | Parameter | Description |
|
||||
|--------|-----------|-------------|
|
||||
| Telemetry | `bifrost.plugins.telemetry.enabled` | Enable metrics collection |
|
||||
| Logging | `bifrost.plugins.logging.enabled` | Enable request logging |
|
||||
| Governance | `bifrost.plugins.governance.enabled` | Enable budget management |
|
||||
| Semantic Cache | `bifrost.plugins.semanticCache.enabled` | Enable semantic caching |
|
||||
| OTEL | `bifrost.plugins.otel.enabled` | Enable OpenTelemetry integration |
|
||||
| Maxim | `bifrost.plugins.maxim.enabled` | Enable Maxim observability |
|
||||
| Datadog | `bifrost.plugins.datadog.enabled` | Enable Datadog APM integration |
|
||||
| Custom | `bifrost.plugins.custom` | Array of custom/dynamic plugins |
|
||||
|
||||
#### Custom Plugins
|
||||
|
||||
You can add custom/dynamic plugins using the `bifrost.plugins.custom` array:
|
||||
|
||||
```yaml
|
||||
bifrost:
|
||||
plugins:
|
||||
custom:
|
||||
- name: "my-custom-plugin"
|
||||
enabled: true
|
||||
path: "/plugins/my-plugin.so"
|
||||
version: 1
|
||||
placement: "pre_builtin" # or "post_builtin" (default)
|
||||
order: 0 # execution order within placement group
|
||||
config:
|
||||
key: value
|
||||
```
|
||||
|
||||
### Client Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `bifrost.client.disableDbPingsInHealth` | Disable DB pings in health check | `false` |
|
||||
| `bifrost.client.headerFilterConfig.allowlist` | Headers allowed to forward to LLM providers | `[]` |
|
||||
| `bifrost.client.headerFilterConfig.denylist` | Headers blocked from forwarding | `[]` |
|
||||
|
||||
### MCP Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `bifrost.mcp.enabled` | Enable MCP (Model Context Protocol) | `false` |
|
||||
| `bifrost.mcp.clientConfigs` | Array of MCP client configurations | `[]` |
|
||||
| `bifrost.mcp.toolManagerConfig.toolExecutionTimeout` | Tool execution timeout in seconds | `30` |
|
||||
| `bifrost.mcp.toolManagerConfig.maxAgentDepth` | Maximum agent depth | `10` |
|
||||
|
||||
### Ingress Configuration
|
||||
|
||||
```yaml
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: bifrost.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: bifrost-tls
|
||||
hosts:
|
||||
- bifrost.example.com
|
||||
```
|
||||
|
||||
### Auto-scaling Configuration
|
||||
|
||||
```yaml
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 2
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 80
|
||||
targetMemoryUtilizationPercentage: 80
|
||||
```
|
||||
|
||||
### Referencing Secrets in MCP Headers
|
||||
|
||||
`bifrost.mcp.clientConfigs[].headers` is a free-form `map<string, string>`
|
||||
whose values can contain auth tokens. The chart does not wrap this map with
|
||||
a bespoke `secretRef` — a per-header dict would explode the values surface.
|
||||
Instead, use the standard pattern:
|
||||
|
||||
1. Write `env.MY_HEADER_VAR` as the header value in `values.yaml`:
|
||||
```yaml
|
||||
bifrost:
|
||||
mcp:
|
||||
clientConfigs:
|
||||
- name: "my-mcp"
|
||||
connectionType: "http"
|
||||
headers:
|
||||
Authorization: "env.MY_MCP_AUTH"
|
||||
```
|
||||
2. Inject the env var into the pod via the chart's top-level `envFrom:` or
|
||||
`env:` pass-through — e.g., in `values.yaml`:
|
||||
```yaml
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: my-mcp-auth-secret
|
||||
# OR:
|
||||
env:
|
||||
- name: MY_MCP_AUTH
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: my-mcp-auth-secret
|
||||
key: authorization
|
||||
```
|
||||
|
||||
For `bifrost.mcp.clientConfigs[].connectionString` itself, prefer the
|
||||
chart-native `secretRef` (`name` + `connectionStringKey`) instead — the
|
||||
chart will inject `BIFROST_MCP_<NAME>_CONNECTION_STRING` and rewrite the
|
||||
config automatically.
|
||||
|
||||
## Example Configurations
|
||||
|
||||
The chart includes pre-configured examples in `values-examples/`:
|
||||
|
||||
| Configuration | Description |
|
||||
|---------------|-------------|
|
||||
| `sqlite-only.yaml` | Simple setup with SQLite (local development) |
|
||||
| `postgres-only.yaml` | PostgreSQL for config and logs |
|
||||
| `mixed-backend.yaml` | SQLite for config + PostgreSQL for logs (mixed backend) |
|
||||
| `postgres-weaviate.yaml` | PostgreSQL + Weaviate for semantic caching |
|
||||
| `postgres-redis.yaml` | PostgreSQL + Redis for semantic caching |
|
||||
| `postgres-qdrant.yaml` | PostgreSQL + Qdrant for semantic caching |
|
||||
| `sqlite-weaviate.yaml` | SQLite + Weaviate |
|
||||
| `sqlite-redis.yaml` | SQLite + Redis |
|
||||
| `sqlite-qdrant.yaml` | SQLite + Qdrant |
|
||||
| `external-postgres.yaml` | Using external PostgreSQL |
|
||||
| `production-ha.yaml` | Production high-availability setup |
|
||||
|
||||
### Using Example Configurations
|
||||
|
||||
```bash
|
||||
# From Helm repository
|
||||
helm install bifrost bifrost/bifrost \
|
||||
-f https://raw.githubusercontent.com/maximhq/bifrost/main/helm-charts/bifrost/values-examples/postgres-only.yaml \
|
||||
--set image.tag=v1.5.2
|
||||
|
||||
# From local source
|
||||
helm install bifrost ./bifrost -f ./bifrost/values-examples/postgres-only.yaml
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
For production deployments, we recommend:
|
||||
|
||||
1. **Use PostgreSQL** for reliable data persistence
|
||||
2. **Enable semantic caching** with Weaviate, Redis, or Qdrant
|
||||
3. **Configure auto-scaling** for handling variable load
|
||||
4. **Set up Ingress** with TLS termination
|
||||
5. **Use external secrets** for sensitive data
|
||||
|
||||
### Example Production Setup
|
||||
|
||||
```yaml
|
||||
# production-values.yaml
|
||||
replicaCount: 3
|
||||
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
|
||||
storage:
|
||||
mode: postgres
|
||||
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
password: "SECURE_PASSWORD_HERE"
|
||||
primary:
|
||||
persistence:
|
||||
size: 50Gi
|
||||
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: weaviate
|
||||
weaviate:
|
||||
enabled: true
|
||||
persistence:
|
||||
size: 50Gi
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: bifrost.yourdomain.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: bifrost-tls
|
||||
hosts:
|
||||
- bifrost.yourdomain.com
|
||||
|
||||
bifrost:
|
||||
client:
|
||||
initialPoolSize: 1000
|
||||
allowedOrigins:
|
||||
- "https://yourdomain.com"
|
||||
plugins:
|
||||
semanticCache:
|
||||
enabled: true
|
||||
telemetry:
|
||||
enabled: true
|
||||
logging:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
```bash
|
||||
# Update repository
|
||||
helm repo update
|
||||
|
||||
# Upgrade release
|
||||
helm upgrade bifrost bifrost/bifrost --set image.tag=v1.5.2
|
||||
|
||||
# Or with custom values
|
||||
helm upgrade bifrost bifrost/bifrost -f my-values.yaml
|
||||
```
|
||||
|
||||
## Uninstalling
|
||||
|
||||
```bash
|
||||
# Uninstall release
|
||||
helm uninstall bifrost
|
||||
|
||||
# If you want to delete persistent volumes
|
||||
kubectl delete pvc -l app.kubernetes.io/name=bifrost
|
||||
```
|
||||
|
||||
## Accessing Bifrost
|
||||
|
||||
After installation, access Bifrost using one of these methods:
|
||||
|
||||
### Port Forwarding (Development)
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/bifrost 8080:8080
|
||||
# Then visit http://localhost:8080
|
||||
```
|
||||
|
||||
### LoadBalancer
|
||||
|
||||
```yaml
|
||||
service:
|
||||
type: LoadBalancer
|
||||
```
|
||||
|
||||
### Ingress
|
||||
|
||||
Configure the `ingress` section as shown above.
|
||||
|
||||
## Monitoring
|
||||
|
||||
Bifrost exposes Prometheus metrics at `/metrics`:
|
||||
|
||||
```bash
|
||||
# Get metrics
|
||||
curl http://localhost:8080/metrics
|
||||
```
|
||||
|
||||
For OpenTelemetry integration:
|
||||
|
||||
```yaml
|
||||
bifrost:
|
||||
plugins:
|
||||
otel:
|
||||
enabled: true
|
||||
config:
|
||||
service_name: "bifrost"
|
||||
collector_url: "http://otel-collector:4317"
|
||||
trace_type: "genai_extension"
|
||||
protocol: "grpc"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Check Pod Status
|
||||
|
||||
```bash
|
||||
kubectl get pods -l app.kubernetes.io/name=bifrost
|
||||
kubectl describe pod <pod-name>
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
kubectl logs -l app.kubernetes.io/name=bifrost -f
|
||||
```
|
||||
|
||||
### Check Configuration
|
||||
|
||||
```bash
|
||||
# View generated configmap
|
||||
kubectl get configmap bifrost -o yaml
|
||||
|
||||
# View generated secrets
|
||||
kubectl get secret bifrost -o yaml
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Pod stuck in Pending state:**
|
||||
- Check if PersistentVolume is available: `kubectl get pv`
|
||||
- Check storage class: `kubectl get storageclass`
|
||||
|
||||
**Pod CrashLoopBackOff:**
|
||||
- Check logs: `kubectl logs <pod-name>`
|
||||
- Verify environment variables and secrets
|
||||
|
||||
**Cannot connect to PostgreSQL:**
|
||||
- Ensure PostgreSQL pod is running
|
||||
- Check connection string in configmap/secrets
|
||||
- Verify network policies allow connectivity
|
||||
|
||||
## Resources
|
||||
|
||||
- [Bifrost Documentation](https://docs.getbifrost.ai)
|
||||
- [GitHub Repository](https://github.com/maximhq/bifrost)
|
||||
- [Docker Hub](https://hub.docker.com/r/maximhq/bifrost)
|
||||
- [Discord Community](https://discord.gg/exN5KAydbU)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the Apache 2.0 License - see the [LICENSE](../LICENSE) file for details.
|
||||
|
||||
Built with ❤️ by [Maxim](https://github.com/maximhq)
|
||||
|
||||
393
helm-charts/bifrost/scripts/generate-values.sh
Executable file
393
helm-charts/bifrost/scripts/generate-values.sh
Executable file
@@ -0,0 +1,393 @@
|
||||
#!/bin/bash
|
||||
# Bifrost Values File Generator
|
||||
# This interactive script helps you generate a custom values.yaml file
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_info() { echo -e "${BLUE}ℹ ${NC}$1"; }
|
||||
print_success() { echo -e "${GREEN}✓ ${NC}$1"; }
|
||||
print_warning() { echo -e "${YELLOW}⚠ ${NC}$1"; }
|
||||
print_error() { echo -e "${RED}✗ ${NC}$1"; }
|
||||
|
||||
print_banner() {
|
||||
echo ""
|
||||
echo -e "${BLUE}╔═══════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}║ Bifrost Values Generator ║${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}╚═══════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_banner
|
||||
|
||||
OUTPUT_FILE="my-values.yaml"
|
||||
|
||||
# Storage configuration - per-store backend selection
|
||||
echo "1. Select backend for Config Store:"
|
||||
echo " 1) SQLite (simple, single node)"
|
||||
echo " 2) PostgreSQL (production, scalable)"
|
||||
read -p "Choice [1-2]: " config_store_choice
|
||||
|
||||
case $config_store_choice in
|
||||
1) CONFIG_STORE_TYPE="sqlite" ;;
|
||||
2) CONFIG_STORE_TYPE="postgres" ;;
|
||||
*) print_error "Invalid choice"; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "2. Select backend for Logs Store:"
|
||||
echo " 1) SQLite (simple, single node)"
|
||||
echo " 2) PostgreSQL (production, scalable)"
|
||||
read -p "Choice [1-2]: " logs_store_choice
|
||||
|
||||
case $logs_store_choice in
|
||||
1) LOGS_STORE_TYPE="sqlite" ;;
|
||||
2) LOGS_STORE_TYPE="postgres" ;;
|
||||
*) print_error "Invalid choice"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Determine if PostgreSQL is needed (for either store)
|
||||
if [[ "$CONFIG_STORE_TYPE" == "postgres" ]] || [[ "$LOGS_STORE_TYPE" == "postgres" ]]; then
|
||||
NEEDS_POSTGRES="true"
|
||||
else
|
||||
NEEDS_POSTGRES="false"
|
||||
fi
|
||||
|
||||
# Determine if SQLite persistence is needed (for either store)
|
||||
if [[ "$CONFIG_STORE_TYPE" == "sqlite" ]] || [[ "$LOGS_STORE_TYPE" == "sqlite" ]]; then
|
||||
NEEDS_SQLITE_PERSISTENCE="true"
|
||||
else
|
||||
NEEDS_SQLITE_PERSISTENCE="false"
|
||||
fi
|
||||
|
||||
# Vector store
|
||||
echo ""
|
||||
echo "3. Do you need vector store for semantic caching?"
|
||||
read -p "Enable vector store? (y/n): " vector_choice
|
||||
|
||||
if [[ "$vector_choice" =~ ^[Yy]$ ]]; then
|
||||
echo " 1) Weaviate"
|
||||
echo " 2) Redis"
|
||||
echo " 3) Qdrant"
|
||||
read -p "Choice [1-3]: " vector_type_choice
|
||||
case $vector_type_choice in
|
||||
1) VECTOR_TYPE="weaviate" ;;
|
||||
2) VECTOR_TYPE="redis" ;;
|
||||
3) VECTOR_TYPE="qdrant" ;;
|
||||
*) print_error "Invalid choice"; exit 1 ;;
|
||||
esac
|
||||
VECTOR_ENABLED="true"
|
||||
else
|
||||
VECTOR_ENABLED="false"
|
||||
VECTOR_TYPE="none"
|
||||
fi
|
||||
|
||||
# Deployment type
|
||||
echo ""
|
||||
echo "4. Deployment type:"
|
||||
echo " 1) Development (1 replica, minimal resources)"
|
||||
echo " 2) Production (3+ replicas, auto-scaling)"
|
||||
read -p "Choice [1-2]: " deploy_choice
|
||||
|
||||
case $deploy_choice in
|
||||
1)
|
||||
REPLICAS="1"
|
||||
AUTOSCALING="false"
|
||||
CPU_REQUEST="250m"
|
||||
MEM_REQUEST="256Mi"
|
||||
CPU_LIMIT="1000m"
|
||||
MEM_LIMIT="1Gi"
|
||||
;;
|
||||
2)
|
||||
REPLICAS="3"
|
||||
AUTOSCALING="true"
|
||||
CPU_REQUEST="1000m"
|
||||
MEM_REQUEST="1Gi"
|
||||
CPU_LIMIT="4000m"
|
||||
MEM_LIMIT="4Gi"
|
||||
;;
|
||||
*) print_error "Invalid choice"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Ingress
|
||||
echo ""
|
||||
read -p "5. Do you want to enable Ingress? (y/n): " ingress_choice
|
||||
if [[ "$ingress_choice" =~ ^[Yy]$ ]]; then
|
||||
INGRESS_ENABLED="true"
|
||||
read -p " Enter your domain (e.g., bifrost.yourdomain.com): " DOMAIN
|
||||
else
|
||||
INGRESS_ENABLED="false"
|
||||
DOMAIN="bifrost.local"
|
||||
fi
|
||||
|
||||
# Encryption key
|
||||
echo ""
|
||||
read -p "6. Enter encryption key (leave empty to skip): " ENCRYPTION_KEY
|
||||
|
||||
# Check if output file already exists
|
||||
if [[ -f "$OUTPUT_FILE" ]]; then
|
||||
echo ""
|
||||
print_warning "File '$OUTPUT_FILE' already exists."
|
||||
read -p "Do you want to overwrite it? (y/n): " overwrite_choice
|
||||
if [[ ! "$overwrite_choice" =~ ^[Yy]$ ]]; then
|
||||
print_info "Generation aborted. No files were modified."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Generate the file
|
||||
print_info "Generating values file..."
|
||||
|
||||
cat > "$OUTPUT_FILE" <<EOF
|
||||
# Generated Bifrost values file
|
||||
# Generated on: $(date)
|
||||
|
||||
# Deployment configuration
|
||||
replicaCount: ${REPLICAS}
|
||||
|
||||
autoscaling:
|
||||
enabled: ${AUTOSCALING}
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 70
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: ${CPU_LIMIT}
|
||||
memory: ${MEM_LIMIT}
|
||||
requests:
|
||||
cpu: ${CPU_REQUEST}
|
||||
memory: ${MEM_REQUEST}
|
||||
|
||||
# Storage configuration (per-store backend selection)
|
||||
storage:
|
||||
mode: sqlite # Default fallback
|
||||
EOF
|
||||
|
||||
if [[ "$NEEDS_SQLITE_PERSISTENCE" == "true" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
configStore:
|
||||
enabled: true
|
||||
type: ${CONFIG_STORE_TYPE}
|
||||
logsStore:
|
||||
enabled: true
|
||||
type: ${LOGS_STORE_TYPE}
|
||||
|
||||
EOF
|
||||
|
||||
# PostgreSQL configuration
|
||||
if [[ "$NEEDS_POSTGRES" == "true" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
# PostgreSQL configuration (used by: $(
|
||||
stores=""
|
||||
[[ "$CONFIG_STORE_TYPE" == "postgres" ]] && stores="config store"
|
||||
[[ "$LOGS_STORE_TYPE" == "postgres" ]] && { [[ -n "$stores" ]] && stores="$stores, logs store" || stores="logs store"; }
|
||||
echo "$stores"
|
||||
))
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
username: bifrost
|
||||
password: "CHANGE_ME_SECURE_PASSWORD"
|
||||
database: bifrost
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 20Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
EOF
|
||||
else
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
# PostgreSQL disabled (using SQLite for all stores)
|
||||
postgresql:
|
||||
enabled: false
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Vector store configuration
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
# Vector store configuration
|
||||
vectorStore:
|
||||
enabled: ${VECTOR_ENABLED}
|
||||
type: ${VECTOR_TYPE}
|
||||
EOF
|
||||
|
||||
if [[ "$VECTOR_TYPE" == "weaviate" ]] && [[ "$VECTOR_ENABLED" == "true" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
weaviate:
|
||||
enabled: true
|
||||
replicas: 1
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
EOF
|
||||
elif [[ "$VECTOR_TYPE" == "redis" ]] && [[ "$VECTOR_ENABLED" == "true" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
redis:
|
||||
enabled: true
|
||||
auth:
|
||||
enabled: true
|
||||
password: "CHANGE_ME_REDIS_PASSWORD"
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 8Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
EOF
|
||||
elif [[ "$VECTOR_TYPE" == "qdrant" ]] && [[ "$VECTOR_ENABLED" == "true" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
qdrant:
|
||||
enabled: true
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Ingress
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
|
||||
# Ingress configuration
|
||||
ingress:
|
||||
enabled: ${INGRESS_ENABLED}
|
||||
EOF
|
||||
|
||||
if [[ "$INGRESS_ENABLED" == "true" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: ${DOMAIN}
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: bifrost-tls
|
||||
hosts:
|
||||
- ${DOMAIN}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Bifrost configuration
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
|
||||
# Bifrost application configuration
|
||||
bifrost:
|
||||
EOF
|
||||
|
||||
if [[ -n "$ENCRYPTION_KEY" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
encryptionKey: "${ENCRYPTION_KEY}"
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
|
||||
client:
|
||||
enableLogging: true
|
||||
allowedOrigins:
|
||||
- "*"
|
||||
maxRequestBodySizeMb: 100
|
||||
|
||||
# Add your provider keys here
|
||||
providers: {}
|
||||
# Example:
|
||||
# openai:
|
||||
# keys:
|
||||
# - value: "sk-..."
|
||||
# weight: 1
|
||||
# anthropic:
|
||||
# keys:
|
||||
# - value: "sk-ant-..."
|
||||
# weight: 1
|
||||
|
||||
plugins:
|
||||
telemetry:
|
||||
enabled: true
|
||||
config: {}
|
||||
|
||||
logging:
|
||||
enabled: true
|
||||
config: {}
|
||||
EOF
|
||||
|
||||
if [[ "$VECTOR_ENABLED" == "true" ]]; then
|
||||
cat >> "$OUTPUT_FILE" <<EOF
|
||||
|
||||
semanticCache:
|
||||
enabled: true
|
||||
config:
|
||||
provider: "openai"
|
||||
keys:
|
||||
- "sk-..." # Add your OpenAI key for embeddings
|
||||
embeddingModel: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
EOF
|
||||
fi
|
||||
|
||||
print_success "Values file generated: $OUTPUT_FILE"
|
||||
echo ""
|
||||
print_info "Storage configuration:"
|
||||
print_info " - Config Store: ${CONFIG_STORE_TYPE}"
|
||||
print_info " - Logs Store: ${LOGS_STORE_TYPE}"
|
||||
echo ""
|
||||
print_warning "Please review and edit the generated file:"
|
||||
print_warning " - Add your provider API keys"
|
||||
if [[ "$NEEDS_POSTGRES" == "true" ]]; then
|
||||
print_warning " - Change PostgreSQL password"
|
||||
fi
|
||||
if [[ "$VECTOR_TYPE" == "redis" ]] && [[ "$VECTOR_ENABLED" == "true" ]]; then
|
||||
print_warning " - Change Redis password"
|
||||
fi
|
||||
if [[ -z "$ENCRYPTION_KEY" ]]; then
|
||||
print_warning " - Add encryption key for production"
|
||||
fi
|
||||
echo ""
|
||||
print_info "Install with: helm install bifrost ./bifrost -f $OUTPUT_FILE"
|
||||
|
||||
229
helm-charts/bifrost/scripts/install.sh
Executable file
229
helm-charts/bifrost/scripts/install.sh
Executable file
@@ -0,0 +1,229 @@
|
||||
#!/bin/bash
|
||||
# Bifrost Helm Chart Installation Script
|
||||
# This script helps you install Bifrost with different configurations
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Print colored output
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ ${NC}$1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓ ${NC}$1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠ ${NC}$1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗ ${NC}$1"
|
||||
}
|
||||
|
||||
# Print banner
|
||||
print_banner() {
|
||||
echo ""
|
||||
echo -e "${BLUE}╔═══════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}║ Bifrost Helm Chart Installer ║${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}╚═══════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
check_prerequisites() {
|
||||
print_info "Checking prerequisites..."
|
||||
|
||||
if ! command -v helm &> /dev/null; then
|
||||
print_error "Helm is not installed. Please install Helm 3.2.0 or later."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
print_error "kubectl is not installed. Please install kubectl."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check kubectl connection
|
||||
if ! kubectl cluster-info &> /dev/null; then
|
||||
print_error "Cannot connect to Kubernetes cluster. Please check your kubeconfig."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "All prerequisites met"
|
||||
}
|
||||
|
||||
# Show menu
|
||||
show_menu() {
|
||||
echo ""
|
||||
echo "Select a deployment configuration:"
|
||||
echo ""
|
||||
echo " 1) SQLite only (simple, local development)"
|
||||
echo " 2) PostgreSQL only (production-ready database)"
|
||||
echo " 3) PostgreSQL + Weaviate (semantic caching with Weaviate)"
|
||||
echo " 4) PostgreSQL + Redis (semantic caching with Redis)"
|
||||
echo " 5) SQLite + Weaviate (local dev with semantic caching)"
|
||||
echo " 6) SQLite + Redis (local dev with Redis caching)"
|
||||
echo " 7) External PostgreSQL (use your own database)"
|
||||
echo " 8) Production HA (high-availability setup)"
|
||||
echo " 9) Custom (use your own values file)"
|
||||
echo ""
|
||||
echo " 0) Exit"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Get user input
|
||||
get_input() {
|
||||
read -p "Enter your choice [0-9]: " choice
|
||||
case $choice in
|
||||
1) CONFIG="sqlite-only" ;;
|
||||
2) CONFIG="postgres-only" ;;
|
||||
3) CONFIG="postgres-weaviate" ;;
|
||||
4) CONFIG="postgres-redis" ;;
|
||||
5) CONFIG="sqlite-weaviate" ;;
|
||||
6) CONFIG="sqlite-redis" ;;
|
||||
7) CONFIG="external-postgres" ;;
|
||||
8) CONFIG="production-ha" ;;
|
||||
9) CONFIG="custom" ;;
|
||||
0) exit 0 ;;
|
||||
*)
|
||||
print_error "Invalid choice. Please try again."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get release name
|
||||
get_release_name() {
|
||||
read -p "Enter release name (default: bifrost): " RELEASE_NAME
|
||||
RELEASE_NAME=${RELEASE_NAME:-bifrost}
|
||||
}
|
||||
|
||||
# Get namespace
|
||||
get_namespace() {
|
||||
read -p "Enter namespace (default: default): " NAMESPACE
|
||||
NAMESPACE=${NAMESPACE:-default}
|
||||
|
||||
# Check if namespace exists
|
||||
if ! kubectl get namespace "$NAMESPACE" &> /dev/null; then
|
||||
read -p "Namespace '$NAMESPACE' does not exist. Create it? (y/n): " CREATE_NS
|
||||
if [[ "$CREATE_NS" =~ ^[Yy]$ ]]; then
|
||||
kubectl create namespace "$NAMESPACE"
|
||||
print_success "Namespace '$NAMESPACE' created"
|
||||
else
|
||||
print_error "Installation aborted"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Get custom values file
|
||||
get_custom_values() {
|
||||
read -p "Enter path to custom values file: " CUSTOM_VALUES
|
||||
if [[ ! -f "$CUSTOM_VALUES" ]]; then
|
||||
print_error "File not found: $CUSTOM_VALUES"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install chart
|
||||
install_chart() {
|
||||
local values_file=""
|
||||
|
||||
if [[ "$CONFIG" == "custom" ]]; then
|
||||
# Validate that CUSTOM_VALUES is non-empty
|
||||
if [[ -z "$CUSTOM_VALUES" ]]; then
|
||||
print_error "Custom values file path is empty"
|
||||
exit 1
|
||||
fi
|
||||
values_file="$CUSTOM_VALUES"
|
||||
# Validate that the custom values file exists and is a regular file
|
||||
if [[ ! -f "$values_file" ]]; then
|
||||
print_error "Custom values file does not exist or is not a regular file: $values_file"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
values_file="${CHART_DIR}/values-examples/${CONFIG}.yaml"
|
||||
# Validate that the predefined values file exists
|
||||
if [[ ! -f "$values_file" ]]; then
|
||||
print_error "Values file does not exist: $values_file"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
print_info "Installing Bifrost..."
|
||||
print_info "Release: $RELEASE_NAME"
|
||||
print_info "Namespace: $NAMESPACE"
|
||||
print_info "Configuration: $CONFIG"
|
||||
echo ""
|
||||
|
||||
# Ask for confirmation
|
||||
read -p "Proceed with installation? (y/n): " CONFIRM
|
||||
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
|
||||
print_warning "Installation cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Run helm install with explicit chart directory
|
||||
if helm install "$RELEASE_NAME" "$CHART_DIR" \
|
||||
--namespace "$NAMESPACE" \
|
||||
-f "$values_file" \
|
||||
--create-namespace; then
|
||||
|
||||
print_success "Bifrost installed successfully!"
|
||||
echo ""
|
||||
print_info "To check the status:"
|
||||
echo " helm status $RELEASE_NAME -n $NAMESPACE"
|
||||
echo ""
|
||||
print_info "To get the application URL:"
|
||||
echo " kubectl --namespace $NAMESPACE port-forward svc/$RELEASE_NAME 8080:8080"
|
||||
echo " Then visit: http://localhost:8080"
|
||||
echo ""
|
||||
print_info "To view logs:"
|
||||
echo " kubectl logs -l app.kubernetes.io/name=bifrost -n $NAMESPACE -f"
|
||||
echo ""
|
||||
else
|
||||
print_error "Installation failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
print_banner
|
||||
check_prerequisites
|
||||
|
||||
while true; do
|
||||
show_menu
|
||||
if get_input; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
get_release_name
|
||||
get_namespace
|
||||
|
||||
if [[ "$CONFIG" == "custom" ]]; then
|
||||
get_custom_values
|
||||
fi
|
||||
|
||||
# Set explicit chart directory (parent of scripts directory)
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CHART_DIR="$SCRIPT_DIR/.."
|
||||
|
||||
install_chart
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main
|
||||
|
||||
94
helm-charts/bifrost/scripts/validate.sh
Executable file
94
helm-charts/bifrost/scripts/validate.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
# Bifrost Helm Chart Validation Script
|
||||
# This script validates the Helm chart before installation
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ ${NC}$1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓ ${NC}$1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗ ${NC}$1"
|
||||
}
|
||||
|
||||
print_banner() {
|
||||
echo ""
|
||||
echo -e "${BLUE}╔═══════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}║ Bifrost Chart Validator ║${NC}"
|
||||
echo -e "${BLUE}║ ║${NC}"
|
||||
echo -e "${BLUE}╚═══════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Set explicit chart directory (parent of scripts directory)
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CHART_DIR="$SCRIPT_DIR/.."
|
||||
|
||||
print_banner
|
||||
|
||||
# Check if Helm is installed
|
||||
print_info "Checking Helm installation..."
|
||||
if ! command -v helm &> /dev/null; then
|
||||
print_error "Helm is not installed"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Helm is installed"
|
||||
|
||||
# Lint the chart
|
||||
print_info "Linting Helm chart..."
|
||||
if helm lint "$CHART_DIR"; then
|
||||
print_success "Chart linting passed"
|
||||
else
|
||||
print_error "Chart linting failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Template the chart with default values
|
||||
print_info "Templating chart with default values..."
|
||||
if helm template test-release "$CHART_DIR" > /dev/null; then
|
||||
print_success "Default values template successful"
|
||||
else
|
||||
print_error "Default values template failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test all example configurations
|
||||
print_info "Testing example configurations..."
|
||||
for config in "$CHART_DIR"/values-examples/*.yaml; do
|
||||
config_name=$(basename "$config")
|
||||
print_info " Testing $config_name..."
|
||||
if helm template test-release "$CHART_DIR" -f "$config" > /dev/null; then
|
||||
print_success " $config_name: OK"
|
||||
else
|
||||
print_error " $config_name: FAILED"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Dry run install
|
||||
print_info "Performing dry-run installation..."
|
||||
if helm install test-release "$CHART_DIR" --dry-run --debug > /dev/null 2>&1; then
|
||||
print_success "Dry-run installation successful"
|
||||
else
|
||||
print_error "Dry-run installation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_success "All validation checks passed!"
|
||||
echo ""
|
||||
print_info "Chart is ready for installation"
|
||||
|
||||
59
helm-charts/bifrost/templates/NOTES.txt
Normal file
59
helm-charts/bifrost/templates/NOTES.txt
Normal file
@@ -0,0 +1,59 @@
|
||||
Bifrost has been installed!
|
||||
|
||||
{{- if .Values.ingress.enabled }}
|
||||
|
||||
1. Access Bifrost at:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .host }}
|
||||
{{- end }}
|
||||
|
||||
{{- else if eq .Values.service.type "LoadBalancer" }}
|
||||
|
||||
1. Get the LoadBalancer IP:
|
||||
kubectl get svc {{ include "bifrost.fullname" . }} -n {{ .Release.Namespace }}
|
||||
|
||||
2. Access Bifrost at:
|
||||
http://<EXTERNAL-IP>:{{ .Values.service.port }}
|
||||
|
||||
{{- else if eq .Values.service.type "NodePort" }}
|
||||
|
||||
1. Get the NodePort:
|
||||
export NODE_PORT=$(kubectl get svc {{ include "bifrost.fullname" . }} -n {{ .Release.Namespace }} -o jsonpath='{.spec.ports[0].nodePort}')
|
||||
export NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}' || kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
|
||||
|
||||
2. Access Bifrost at:
|
||||
http://$NODE_IP:$NODE_PORT
|
||||
|
||||
{{- else }}
|
||||
|
||||
1. Port-forward to access Bifrost:
|
||||
kubectl port-forward svc/{{ include "bifrost.fullname" . }} 8080:{{ .Values.service.port }} -n {{ .Release.Namespace }}
|
||||
|
||||
2. Access Bifrost at:
|
||||
http://localhost:8080
|
||||
|
||||
{{- end }}
|
||||
|
||||
Configuration:
|
||||
- Storage Mode: {{ .Values.storage.mode }}
|
||||
{{- if eq .Values.storage.mode "postgres" }}
|
||||
{{- if .Values.postgresql.enabled }}
|
||||
- PostgreSQL: Deployed
|
||||
{{- else }}
|
||||
- PostgreSQL: External ({{ .Values.postgresql.external.host }})
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- SQLite: Using persistent volume ({{ .Values.storage.persistence.size }})
|
||||
{{- end }}
|
||||
{{- if and .Values.vectorStore.enabled (ne .Values.vectorStore.type "none") }}
|
||||
- Vector Store: {{ .Values.vectorStore.type }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.enabled }}
|
||||
- Autoscaling: Enabled ({{ .Values.autoscaling.minReplicas }}-{{ .Values.autoscaling.maxReplicas }} replicas)
|
||||
{{- else }}
|
||||
- Replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
|
||||
Metrics: http://{{ include "bifrost.fullname" . }}:{{ .Values.service.port }}/metrics
|
||||
|
||||
For documentation, visit: https://www.getbifrost.ai/docs
|
||||
1446
helm-charts/bifrost/templates/_helpers.tpl
Normal file
1446
helm-charts/bifrost/templates/_helpers.tpl
Normal file
File diff suppressed because it is too large
Load Diff
10
helm-charts/bifrost/templates/configmap.yaml
Normal file
10
helm-charts/bifrost/templates/configmap.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.json: |
|
||||
{{- include "bifrost.config" . | nindent 4 }}
|
||||
296
helm-charts/bifrost/templates/deployment.yaml
Normal file
296
helm-charts/bifrost/templates/deployment.yaml
Normal file
@@ -0,0 +1,296 @@
|
||||
{{- /* Use Deployment when: postgres mode, OR sqlite without persistence, OR sqlite with existingClaim */}}
|
||||
{{- /* StatefulSet is used for: sqlite mode with persistence enabled and no existingClaim */}}
|
||||
{{- $useStatefulSet := and (eq .Values.storage.mode "sqlite") .Values.storage.persistence.enabled (not .Values.storage.persistence.existingClaim) }}
|
||||
{{- if not $useStatefulSet }}
|
||||
{{- if not .Values.image.tag }}
|
||||
{{- fail "ERROR: image.tag is required. Please specify the Bifrost image version (e.g., --set image.tag=v1.3.36). See available tags at https://hub.docker.com/r/maximhq/bifrost/tags" }}
|
||||
{{- end }}
|
||||
{{- include "bifrost.validate" . }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
{{- with .Values.deploymentLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.deploymentAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "bifrost.serverSelectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: server
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "bifrost.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
{{- if .Values.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- with .Values.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.bifrost.port }}
|
||||
protocol: TCP
|
||||
{{- if .Values.bifrost.cluster.enabled }}
|
||||
- name: gossip
|
||||
containerPort: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
protocol: TCP
|
||||
- name: gossip-udp
|
||||
containerPort: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
protocol: UDP
|
||||
{{- end }}
|
||||
env:
|
||||
- name: APP_DIR
|
||||
value: {{ .Values.bifrost.appDir | quote }}
|
||||
- name: APP_PORT
|
||||
value: {{ .Values.bifrost.port | quote }}
|
||||
- name: APP_HOST
|
||||
value: {{ .Values.bifrost.host | quote }}
|
||||
- name: LOG_LEVEL
|
||||
value: {{ .Values.bifrost.logLevel | quote }}
|
||||
- name: LOG_STYLE
|
||||
value: {{ .Values.bifrost.logStyle | quote }}
|
||||
{{- if .Values.bifrost.encryptionKeySecret.name }}
|
||||
- name: BIFROST_ENCRYPTION_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.encryptionKeySecret.name }}
|
||||
key: {{ .Values.bifrost.encryptionKeySecret.key }}
|
||||
{{- end }}
|
||||
{{- if and .Values.bifrost.plugins.semanticCache.enabled .Values.bifrost.plugins.semanticCache.secretRef .Values.bifrost.plugins.semanticCache.secretRef.name }}
|
||||
- name: SEMANTIC_CACHE_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.plugins.semanticCache.secretRef.name }}
|
||||
key: {{ .Values.bifrost.plugins.semanticCache.secretRef.key | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* PostgreSQL password from existing secret */ -}}
|
||||
{{- if and .Values.postgresql.external.enabled .Values.postgresql.external.existingSecret }}
|
||||
- name: BIFROST_POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.postgresql.external.existingSecret }}
|
||||
key: {{ .Values.postgresql.external.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Redis password from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "redis") .Values.vectorStore.redis.external.enabled .Values.vectorStore.redis.external.existingSecret }}
|
||||
- name: BIFROST_REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.redis.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.redis.external.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Weaviate API key from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "weaviate") .Values.vectorStore.weaviate.external.enabled .Values.vectorStore.weaviate.external.existingSecret }}
|
||||
- name: BIFROST_WEAVIATE_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.weaviate.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.weaviate.external.apiKeyKey | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* Qdrant API key from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "qdrant") .Values.vectorStore.qdrant.external.enabled .Values.vectorStore.qdrant.external.existingSecret }}
|
||||
- name: BIFROST_QDRANT_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.qdrant.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.qdrant.external.apiKeyKey | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* Pinecone API key from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "pinecone") .Values.vectorStore.pinecone.external.enabled .Values.vectorStore.pinecone.external.existingSecret }}
|
||||
- name: BIFROST_PINECONE_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.pinecone.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.pinecone.external.apiKeyKey | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* Object storage credentials from existing secret */ -}}
|
||||
{{- if and .Values.storage.logsStore.enabled .Values.storage.logsStore.objectStorage .Values.storage.logsStore.objectStorage.enabled .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
{{- if eq .Values.storage.logsStore.objectStorage.type "s3" }}
|
||||
- name: BIFROST_OBJECT_STORAGE_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.accessKeyIdKey | default "access-key-id" }}
|
||||
optional: true
|
||||
- name: BIFROST_OBJECT_STORAGE_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.secretAccessKeyKey | default "secret-access-key" }}
|
||||
optional: true
|
||||
- name: BIFROST_OBJECT_STORAGE_SESSION_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.sessionTokenKey | default "session-token" }}
|
||||
optional: true
|
||||
- name: BIFROST_OBJECT_STORAGE_ROLE_ARN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.roleArnKey | default "role-arn" }}
|
||||
optional: true
|
||||
{{- end }}
|
||||
{{- if eq .Values.storage.logsStore.objectStorage.type "gcs" }}
|
||||
- name: BIFROST_OBJECT_STORAGE_CREDENTIALS_JSON
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.credentialsJsonKey | default "credentials-json" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- /* Maxim API key from existing secret */ -}}
|
||||
{{- if and .Values.bifrost.plugins.maxim.enabled .Values.bifrost.plugins.maxim.secretRef .Values.bifrost.plugins.maxim.secretRef.name }}
|
||||
- name: BIFROST_MAXIM_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.plugins.maxim.secretRef.name }}
|
||||
key: {{ .Values.bifrost.plugins.maxim.secretRef.key | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* MCP client connection strings from existing secrets (one per client with secretRef.name set) */ -}}
|
||||
{{- if .Values.bifrost.mcp.enabled }}
|
||||
{{- range $idx, $client := .Values.bifrost.mcp.clientConfigs }}
|
||||
{{- if and $client.secretRef $client.secretRef.name }}
|
||||
- name: BIFROST_MCP_{{ regexReplaceAll "[^A-Z0-9]+" (upper $client.name) "_" }}_CONNECTION_STRING
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ $client.secretRef.name }}
|
||||
key: {{ $client.secretRef.connectionStringKey | default "connection-string" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- /* Governance auth credentials from existing secret */ -}}
|
||||
{{- if and .Values.bifrost.governance .Values.bifrost.governance.authConfig .Values.bifrost.governance.authConfig.existingSecret }}
|
||||
- name: BIFROST_ADMIN_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.governance.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.governance.authConfig.usernameKey | default "username" }}
|
||||
- name: BIFROST_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.governance.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.governance.authConfig.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Top-level auth credentials from existing secret (reuses same env vars as governance) */ -}}
|
||||
{{- if and .Values.bifrost.authConfig .Values.bifrost.authConfig.existingSecret (not (and .Values.bifrost.governance .Values.bifrost.governance.authConfig .Values.bifrost.governance.authConfig.existingSecret)) }}
|
||||
- name: BIFROST_ADMIN_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.authConfig.usernameKey | default "username" }}
|
||||
- name: BIFROST_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.authConfig.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Provider secrets */ -}}
|
||||
{{- range $provider, $secret := .Values.bifrost.providerSecrets }}
|
||||
{{- if and $secret.existingSecret $secret.envVar }}
|
||||
- name: {{ $secret.envVar }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ $secret.existingSecret }}
|
||||
key: {{ $secret.key | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.env }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnv }}
|
||||
{{- range $name := keys . | sortAlpha }}
|
||||
- name: {{ $name }}
|
||||
value: {{ index $.Values.extraEnv $name | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.envFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
{{- if eq .Values.storage.mode "sqlite" }}
|
||||
- name: data
|
||||
mountPath: {{ .Values.bifrost.appDir }}
|
||||
{{- end }}
|
||||
- name: config
|
||||
mountPath: {{ .Values.bifrost.appDir }}/config.json
|
||||
subPath: config.json
|
||||
readOnly: true
|
||||
{{- with .Values.volumeMounts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "bifrost.fullname" . }}-config
|
||||
{{- if eq .Values.storage.mode "sqlite" }}
|
||||
- name: data
|
||||
{{- if .Values.storage.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Values.storage.persistence.existingClaim | default (printf "%s-data" (include "bifrost.fullname" .)) }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.volumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- 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 }}
|
||||
{{- end }}
|
||||
38
helm-charts/bifrost/templates/hpa.yaml
Normal file
38
helm-charts/bifrost/templates/hpa.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
{{- if .Values.autoscaling.enabled }}
|
||||
{{- $useStatefulSet := and (eq .Values.storage.mode "sqlite") .Values.storage.persistence.enabled (not .Values.storage.persistence.existingClaim) }}
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: {{ if $useStatefulSet }}StatefulSet{{ else }}Deployment{{ end }}
|
||||
name: {{ include "bifrost.fullname" . }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- with .Values.autoscaling.behavior }}
|
||||
behavior:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
42
helm-charts/bifrost/templates/ingress.yaml
Normal file
42
helm-charts/bifrost/templates/ingress.yaml
Normal file
@@ -0,0 +1,42 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "bifrost.fullname" $ }}
|
||||
port:
|
||||
number: {{ $.Values.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
79
helm-charts/bifrost/templates/postgresql-deployment.yaml
Normal file
79
helm-charts/bifrost/templates/postgresql-deployment.yaml
Normal file
@@ -0,0 +1,79 @@
|
||||
{{- if and (eq .Values.storage.mode "postgres") .Values.postgresql.enabled (not .Values.postgresql.external.enabled) }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: database
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: database
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: database
|
||||
spec:
|
||||
securityContext:
|
||||
fsGroup: 999
|
||||
containers:
|
||||
- name: postgresql
|
||||
image: "{{ .Values.postgresql.image.repository }}:{{ .Values.postgresql.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.postgresql.image.pullPolicy }}
|
||||
ports:
|
||||
- name: postgresql
|
||||
containerPort: 5432
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .Values.postgresql.auth.username | quote }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "bifrost.fullname" . }}-postgresql
|
||||
key: password
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .Values.postgresql.auth.database | quote }}
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- pg_isready -U "{{ .Values.postgresql.auth.username }}"
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- pg_isready -U "{{ .Values.postgresql.auth.username }}"
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
resources:
|
||||
{{- toYaml .Values.postgresql.primary.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: data
|
||||
{{- if .Values.postgresql.primary.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "bifrost.fullname" . }}-postgresql
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
23
helm-charts/bifrost/templates/postgresql-pvc.yaml
Normal file
23
helm-charts/bifrost/templates/postgresql-pvc.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
{{- if and (eq .Values.storage.mode "postgres") .Values.postgresql.enabled (not .Values.postgresql.external.enabled) .Values.postgresql.primary.persistence.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: database
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- if .Values.postgresql.primary.persistence.storageClass }}
|
||||
{{- if (eq "-" .Values.postgresql.primary.persistence.storageClass) }}
|
||||
storageClassName: ""
|
||||
{{- else }}
|
||||
storageClassName: {{ .Values.postgresql.primary.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.postgresql.primary.persistence.size }}
|
||||
{{- end }}
|
||||
20
helm-charts/bifrost/templates/postgresql-service.yaml
Normal file
20
helm-charts/bifrost/templates/postgresql-service.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
{{- if and (eq .Values.storage.mode "postgres") .Values.postgresql.enabled (not .Values.postgresql.external.enabled) }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: database
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: postgresql
|
||||
protocol: TCP
|
||||
name: postgresql
|
||||
selector:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: database
|
||||
{{- end }}
|
||||
65
helm-charts/bifrost/templates/qdrant-deployment.yaml
Normal file
65
helm-charts/bifrost/templates/qdrant-deployment.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "qdrant") .Values.vectorStore.qdrant.enabled (not .Values.vectorStore.qdrant.external.enabled) }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-qdrant
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: vectorstore-qdrant
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: vectorstore-qdrant
|
||||
spec:
|
||||
containers:
|
||||
- name: qdrant
|
||||
image: "{{ .Values.vectorStore.qdrant.image.repository }}:{{ .Values.vectorStore.qdrant.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.vectorStore.qdrant.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 6333
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
containerPort: 6334
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
{{- toYaml .Values.vectorStore.qdrant.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /qdrant/storage
|
||||
volumes:
|
||||
- name: data
|
||||
{{- if .Values.vectorStore.qdrant.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "bifrost.fullname" . }}-qdrant
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
24
helm-charts/bifrost/templates/qdrant-pvc.yaml
Normal file
24
helm-charts/bifrost/templates/qdrant-pvc.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "qdrant") .Values.vectorStore.qdrant.enabled (not .Values.vectorStore.qdrant.external.enabled) .Values.vectorStore.qdrant.persistence.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-qdrant
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore-qdrant
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- if .Values.vectorStore.qdrant.persistence.storageClass }}
|
||||
{{- if (eq "-" .Values.vectorStore.qdrant.persistence.storageClass) }}
|
||||
storageClassName: ""
|
||||
{{- else }}
|
||||
storageClassName: {{ .Values.vectorStore.qdrant.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.vectorStore.qdrant.persistence.size }}
|
||||
{{- end }}
|
||||
|
||||
25
helm-charts/bifrost/templates/qdrant-service.yaml
Normal file
25
helm-charts/bifrost/templates/qdrant-service.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "qdrant") .Values.vectorStore.qdrant.enabled (not .Values.vectorStore.qdrant.external.enabled) }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-qdrant
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore-qdrant
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 6333
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
- port: 6334
|
||||
targetPort: grpc
|
||||
protocol: TCP
|
||||
name: grpc
|
||||
selector:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore-qdrant
|
||||
{{- end }}
|
||||
|
||||
89
helm-charts/bifrost/templates/redis-deployment.yaml
Normal file
89
helm-charts/bifrost/templates/redis-deployment.yaml
Normal file
@@ -0,0 +1,89 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "redis") .Values.vectorStore.redis.enabled (not .Values.vectorStore.redis.external.enabled) }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-redis-master
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: "{{ .Values.vectorStore.redis.image.repository }}:{{ .Values.vectorStore.redis.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.vectorStore.redis.image.pullPolicy }}
|
||||
ports:
|
||||
- name: redis
|
||||
containerPort: 6379
|
||||
protocol: TCP
|
||||
env:
|
||||
{{- if .Values.vectorStore.redis.auth.enabled }}
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "bifrost.fullname" . }}-redis
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if .Values.vectorStore.redis.auth.enabled }}
|
||||
command:
|
||||
- redis-server
|
||||
- --requirepass
|
||||
- $(REDIS_PASSWORD)
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
{{- if .Values.vectorStore.redis.auth.enabled }}
|
||||
redis-cli -a "$REDIS_PASSWORD" ping
|
||||
{{- else }}
|
||||
redis-cli ping
|
||||
{{- end }}
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
{{- if .Values.vectorStore.redis.auth.enabled }}
|
||||
redis-cli -a "$REDIS_PASSWORD" ping
|
||||
{{- else }}
|
||||
redis-cli ping
|
||||
{{- end }}
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
{{- toYaml .Values.vectorStore.redis.master.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
{{- if .Values.vectorStore.redis.master.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "bifrost.fullname" . }}-redis
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
23
helm-charts/bifrost/templates/redis-pvc.yaml
Normal file
23
helm-charts/bifrost/templates/redis-pvc.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "redis") .Values.vectorStore.redis.enabled (not .Values.vectorStore.redis.external.enabled) .Values.vectorStore.redis.master.persistence.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-redis
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- if .Values.vectorStore.redis.master.persistence.storageClass }}
|
||||
{{- if (eq "-" .Values.vectorStore.redis.master.persistence.storageClass) }}
|
||||
storageClassName: ""
|
||||
{{- else }}
|
||||
storageClassName: {{ .Values.vectorStore.redis.master.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.vectorStore.redis.master.persistence.size }}
|
||||
{{- end }}
|
||||
20
helm-charts/bifrost/templates/redis-service.yaml
Normal file
20
helm-charts/bifrost/templates/redis-service.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "redis") .Values.vectorStore.redis.enabled (not .Values.vectorStore.redis.external.enabled) }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-redis-master
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: redis
|
||||
protocol: TCP
|
||||
name: redis
|
||||
selector:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
{{- end }}
|
||||
27
helm-charts/bifrost/templates/secrets.yaml
Normal file
27
helm-charts/bifrost/templates/secrets.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
{{- if and (eq .Values.storage.mode "postgres") .Values.postgresql.enabled (not .Values.postgresql.external.enabled) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: database
|
||||
type: Opaque
|
||||
data:
|
||||
password: {{ .Values.postgresql.auth.password | b64enc | quote }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "redis") .Values.vectorStore.redis.enabled (not .Values.vectorStore.redis.external.enabled) .Values.vectorStore.redis.auth.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-redis
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
type: Opaque
|
||||
data:
|
||||
password: {{ .Values.vectorStore.redis.auth.password | b64enc | quote }}
|
||||
{{- end }}
|
||||
30
helm-charts/bifrost/templates/service-headless.yaml
Normal file
30
helm-charts/bifrost/templates/service-headless.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
{{- if and (eq .Values.storage.mode "sqlite") .Values.storage.persistence.enabled (not .Values.storage.persistence.existingClaim) }}
|
||||
# Headless service for StatefulSet pod DNS resolution
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-headless
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
clusterIP: None
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
{{- if .Values.bifrost.cluster.enabled }}
|
||||
- port: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
targetPort: gossip
|
||||
protocol: TCP
|
||||
name: gossip
|
||||
- port: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
targetPort: gossip-udp
|
||||
protocol: UDP
|
||||
name: gossip-udp
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "bifrost.serverSelectorLabels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
30
helm-charts/bifrost/templates/service.yaml
Normal file
30
helm-charts/bifrost/templates/service.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
{{- if .Values.bifrost.cluster.enabled }}
|
||||
- port: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
targetPort: gossip
|
||||
protocol: TCP
|
||||
name: gossip
|
||||
- port: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
targetPort: gossip-udp
|
||||
protocol: UDP
|
||||
name: gossip-udp
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "bifrost.serverSelectorLabels" . | nindent 4 }}
|
||||
14
helm-charts/bifrost/templates/serviceaccount.yaml
Normal file
14
helm-charts/bifrost/templates/serviceaccount.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "bifrost.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- end }}
|
||||
304
helm-charts/bifrost/templates/stateful.yaml
Normal file
304
helm-charts/bifrost/templates/stateful.yaml
Normal file
@@ -0,0 +1,304 @@
|
||||
{{- /* StatefulSet is used for: sqlite mode with persistence enabled and no existingClaim */}}
|
||||
{{- $useStatefulSet := and (eq .Values.storage.mode "sqlite") .Values.storage.persistence.enabled (not .Values.storage.persistence.existingClaim) }}
|
||||
{{- if $useStatefulSet }}
|
||||
{{- if not .Values.image.tag }}
|
||||
{{- fail "ERROR: image.tag is required. Please specify the Bifrost image version (e.g., --set image.tag=v1.3.36). See available tags at https://hub.docker.com/r/maximhq/bifrost/tags" }}
|
||||
{{- end }}
|
||||
{{- include "bifrost.validate" . }}
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
{{- with .Values.deploymentLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.deploymentAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceName: {{ include "bifrost.fullname" . }}-headless
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "bifrost.serverSelectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: server
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "bifrost.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
{{- if .Values.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- with .Values.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- with .Values.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.bifrost.port }}
|
||||
protocol: TCP
|
||||
{{- if .Values.bifrost.cluster.enabled }}
|
||||
- name: gossip
|
||||
containerPort: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
protocol: TCP
|
||||
- name: gossip-udp
|
||||
containerPort: {{ .Values.bifrost.cluster.gossip.port }}
|
||||
protocol: UDP
|
||||
{{- end }}
|
||||
env:
|
||||
- name: APP_DIR
|
||||
value: {{ .Values.bifrost.appDir | quote }}
|
||||
- name: APP_PORT
|
||||
value: {{ .Values.bifrost.port | quote }}
|
||||
- name: APP_HOST
|
||||
value: {{ .Values.bifrost.host | quote }}
|
||||
- name: LOG_LEVEL
|
||||
value: {{ .Values.bifrost.logLevel | quote }}
|
||||
- name: LOG_STYLE
|
||||
value: {{ .Values.bifrost.logStyle | quote }}
|
||||
{{- if .Values.bifrost.encryptionKeySecret.name }}
|
||||
- name: BIFROST_ENCRYPTION_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.encryptionKeySecret.name }}
|
||||
key: {{ .Values.bifrost.encryptionKeySecret.key }}
|
||||
{{- end }}
|
||||
{{- if and .Values.bifrost.plugins.semanticCache.enabled .Values.bifrost.plugins.semanticCache.secretRef .Values.bifrost.plugins.semanticCache.secretRef.name }}
|
||||
- name: SEMANTIC_CACHE_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.plugins.semanticCache.secretRef.name }}
|
||||
key: {{ .Values.bifrost.plugins.semanticCache.secretRef.key | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* PostgreSQL password from existing secret */ -}}
|
||||
{{- if and .Values.postgresql.external.enabled .Values.postgresql.external.existingSecret }}
|
||||
- name: BIFROST_POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.postgresql.external.existingSecret }}
|
||||
key: {{ .Values.postgresql.external.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Redis password from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "redis") .Values.vectorStore.redis.external.enabled .Values.vectorStore.redis.external.existingSecret }}
|
||||
- name: BIFROST_REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.redis.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.redis.external.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Weaviate API key from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "weaviate") .Values.vectorStore.weaviate.external.enabled .Values.vectorStore.weaviate.external.existingSecret }}
|
||||
- name: BIFROST_WEAVIATE_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.weaviate.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.weaviate.external.apiKeyKey | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* Qdrant API key from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "qdrant") .Values.vectorStore.qdrant.external.enabled .Values.vectorStore.qdrant.external.existingSecret }}
|
||||
- name: BIFROST_QDRANT_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.qdrant.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.qdrant.external.apiKeyKey | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* Pinecone API key from existing secret */ -}}
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "pinecone") .Values.vectorStore.pinecone.external.enabled .Values.vectorStore.pinecone.external.existingSecret }}
|
||||
- name: BIFROST_PINECONE_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.vectorStore.pinecone.external.existingSecret }}
|
||||
key: {{ .Values.vectorStore.pinecone.external.apiKeyKey | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* Object storage credentials from existing secret */ -}}
|
||||
{{- if and .Values.storage.logsStore.enabled .Values.storage.logsStore.objectStorage .Values.storage.logsStore.objectStorage.enabled .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
{{- if eq .Values.storage.logsStore.objectStorage.type "s3" }}
|
||||
- name: BIFROST_OBJECT_STORAGE_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.accessKeyIdKey | default "access-key-id" }}
|
||||
optional: true
|
||||
- name: BIFROST_OBJECT_STORAGE_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.secretAccessKeyKey | default "secret-access-key" }}
|
||||
optional: true
|
||||
- name: BIFROST_OBJECT_STORAGE_SESSION_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.sessionTokenKey | default "session-token" }}
|
||||
optional: true
|
||||
- name: BIFROST_OBJECT_STORAGE_ROLE_ARN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.roleArnKey | default "role-arn" }}
|
||||
optional: true
|
||||
{{- end }}
|
||||
{{- if eq .Values.storage.logsStore.objectStorage.type "gcs" }}
|
||||
- name: BIFROST_OBJECT_STORAGE_CREDENTIALS_JSON
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.logsStore.objectStorage.existingSecret }}
|
||||
key: {{ .Values.storage.logsStore.objectStorage.credentialsJsonKey | default "credentials-json" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- /* Maxim API key from existing secret */ -}}
|
||||
{{- if and .Values.bifrost.plugins.maxim.enabled .Values.bifrost.plugins.maxim.secretRef .Values.bifrost.plugins.maxim.secretRef.name }}
|
||||
- name: BIFROST_MAXIM_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.plugins.maxim.secretRef.name }}
|
||||
key: {{ .Values.bifrost.plugins.maxim.secretRef.key | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- /* MCP client connection strings from existing secrets (one per client with secretRef.name set) */ -}}
|
||||
{{- if .Values.bifrost.mcp.enabled }}
|
||||
{{- range $idx, $client := .Values.bifrost.mcp.clientConfigs }}
|
||||
{{- if and $client.secretRef $client.secretRef.name }}
|
||||
- name: BIFROST_MCP_{{ regexReplaceAll "[^A-Z0-9]+" (upper $client.name) "_" }}_CONNECTION_STRING
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ $client.secretRef.name }}
|
||||
key: {{ $client.secretRef.connectionStringKey | default "connection-string" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- /* Governance auth credentials from existing secret */ -}}
|
||||
{{- if and .Values.bifrost.governance .Values.bifrost.governance.authConfig .Values.bifrost.governance.authConfig.existingSecret }}
|
||||
- name: BIFROST_ADMIN_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.governance.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.governance.authConfig.usernameKey | default "username" }}
|
||||
- name: BIFROST_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.governance.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.governance.authConfig.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Top-level auth credentials from existing secret (reuses same env vars as governance) */ -}}
|
||||
{{- if and .Values.bifrost.authConfig .Values.bifrost.authConfig.existingSecret (not (and .Values.bifrost.governance .Values.bifrost.governance.authConfig .Values.bifrost.governance.authConfig.existingSecret)) }}
|
||||
- name: BIFROST_ADMIN_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.authConfig.usernameKey | default "username" }}
|
||||
- name: BIFROST_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.bifrost.authConfig.existingSecret }}
|
||||
key: {{ .Values.bifrost.authConfig.passwordKey | default "password" }}
|
||||
{{- end }}
|
||||
{{- /* Provider secrets */ -}}
|
||||
{{- range $provider, $secret := .Values.bifrost.providerSecrets }}
|
||||
{{- if and $secret.existingSecret $secret.envVar }}
|
||||
- name: {{ $secret.envVar }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ $secret.existingSecret }}
|
||||
key: {{ $secret.key | default "api-key" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.env }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnv }}
|
||||
{{- range $name := keys . | sortAlpha }}
|
||||
- name: {{ $name }}
|
||||
value: {{ index $.Values.extraEnv $name | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.envFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: {{ .Values.bifrost.appDir }}
|
||||
- name: config
|
||||
mountPath: {{ .Values.bifrost.appDir }}/config.json
|
||||
subPath: config.json
|
||||
readOnly: true
|
||||
{{- with .Values.volumeMounts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "bifrost.fullname" . }}-config
|
||||
{{- with .Values.volumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- 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 }}
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: data
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 10 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.storage.persistence.accessMode }}
|
||||
{{- if .Values.storage.persistence.storageClass }}
|
||||
{{- if (eq "-" .Values.storage.persistence.storageClass) }}
|
||||
storageClassName: ""
|
||||
{{- else }}
|
||||
storageClassName: {{ .Values.storage.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.storage.persistence.size }}
|
||||
{{- end }}
|
||||
|
||||
69
helm-charts/bifrost/templates/weaviate-deployment.yaml
Normal file
69
helm-charts/bifrost/templates/weaviate-deployment.yaml
Normal file
@@ -0,0 +1,69 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "weaviate") .Values.vectorStore.weaviate.enabled (not .Values.vectorStore.weaviate.external.enabled) }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-weaviate
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore
|
||||
spec:
|
||||
replicas: {{ .Values.vectorStore.weaviate.replicas }}
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: vectorstore
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: vectorstore
|
||||
spec:
|
||||
containers:
|
||||
- name: weaviate
|
||||
image: "{{ .Values.vectorStore.weaviate.image.repository }}:{{ .Values.vectorStore.weaviate.image.tag }}"
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
containerPort: 50051
|
||||
protocol: TCP
|
||||
env:
|
||||
{{- range $key, $value := .Values.vectorStore.weaviate.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $value | quote }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /v1/.well-known/live
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /v1/.well-known/ready
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
{{- toYaml .Values.vectorStore.weaviate.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/weaviate
|
||||
volumes:
|
||||
- name: data
|
||||
{{- if .Values.vectorStore.weaviate.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "bifrost.fullname" . }}-weaviate
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
23
helm-charts/bifrost/templates/weaviate-pvc.yaml
Normal file
23
helm-charts/bifrost/templates/weaviate-pvc.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "weaviate") .Values.vectorStore.weaviate.enabled (not .Values.vectorStore.weaviate.external.enabled) }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-weaviate
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- if .Values.vectorStore.weaviate.persistence.storageClass }}
|
||||
{{- if (eq "-" .Values.vectorStore.weaviate.persistence.storageClass) }}
|
||||
storageClassName: ""
|
||||
{{- else }}
|
||||
storageClassName: {{ .Values.vectorStore.weaviate.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.vectorStore.weaviate.persistence.size }}
|
||||
{{- end }}
|
||||
24
helm-charts/bifrost/templates/weaviate-service.yaml
Normal file
24
helm-charts/bifrost/templates/weaviate-service.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
{{- if and .Values.vectorStore.enabled (eq .Values.vectorStore.type "weaviate") .Values.vectorStore.weaviate.enabled (not .Values.vectorStore.weaviate.external.enabled) }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "bifrost.fullname" . }}-weaviate
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "bifrost.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
- port: 50051
|
||||
targetPort: grpc
|
||||
protocol: TCP
|
||||
name: grpc
|
||||
selector:
|
||||
{{- include "bifrost.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: vectorstore
|
||||
{{- end }}
|
||||
36
helm-charts/bifrost/values-examples/external-postgres.yaml
Normal file
36
helm-charts/bifrost/values-examples/external-postgres.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
# Configuration: External PostgreSQL (not deployed by Helm)
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/external-postgres.yaml
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: postgres
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# Use external PostgreSQL
|
||||
postgresql:
|
||||
enabled: false
|
||||
external:
|
||||
enabled: true
|
||||
host: "your-postgres-host.example.com"
|
||||
port: 5432
|
||||
user: bifrost
|
||||
password: "your-secure-password"
|
||||
database: bifrost
|
||||
sslMode: require
|
||||
|
||||
# No vector store
|
||||
vectorStore:
|
||||
enabled: false
|
||||
type: none
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
encryptionKey: "your-encryption-key-here"
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
|
||||
51
helm-charts/bifrost/values-examples/mixed-backend.yaml
Normal file
51
helm-charts/bifrost/values-examples/mixed-backend.yaml
Normal file
@@ -0,0 +1,51 @@
|
||||
# Configuration: SQLite for config store + PostgreSQL for logs store
|
||||
# This demonstrates independent backend selection for each store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/mixed-backend.yaml
|
||||
|
||||
# Storage configuration with mixed backends
|
||||
storage:
|
||||
mode: sqlite # Default fallback (not used when per-store type is set)
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 5Gi
|
||||
configStore:
|
||||
enabled: true
|
||||
type: sqlite # Config store uses SQLite (fast, local, simple)
|
||||
logsStore:
|
||||
enabled: true
|
||||
type: postgres # Logs store uses PostgreSQL (scalable, queryable)
|
||||
|
||||
# Deploy PostgreSQL for logs store
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
username: bifrost
|
||||
password: bifrost_password
|
||||
database: bifrost
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
# No vector store
|
||||
vectorStore:
|
||||
enabled: false
|
||||
type: none
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
# openai:
|
||||
# keys:
|
||||
# - value: "sk-..."
|
||||
# weight: 1
|
||||
46
helm-charts/bifrost/values-examples/postgres-only.yaml
Normal file
46
helm-charts/bifrost/values-examples/postgres-only.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
# Configuration: PostgreSQL for config and logs store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/postgres-only.yaml
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: postgres
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# Deploy PostgreSQL
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
username: bifrost
|
||||
password: bifrost_password
|
||||
database: bifrost
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
# No vector store
|
||||
vectorStore:
|
||||
enabled: false
|
||||
type: none
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
# openai:
|
||||
# keys:
|
||||
# - value: "sk-..."
|
||||
# weight: 1
|
||||
|
||||
82
helm-charts/bifrost/values-examples/postgres-qdrant.yaml
Normal file
82
helm-charts/bifrost/values-examples/postgres-qdrant.yaml
Normal file
@@ -0,0 +1,82 @@
|
||||
# Configuration: PostgreSQL for config/logs + Qdrant for vector store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/postgres-qdrant.yaml
|
||||
#
|
||||
# SECURITY NOTE: This example contains placeholder values that MUST be replaced
|
||||
# before deployment. Specifically:
|
||||
# - PostgreSQL password must be set to a strong, randomly generated value
|
||||
# - Provider API keys must be replaced with real keys
|
||||
# See inline comments for specific requirements.
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: postgres
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# PostgreSQL configuration
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
username: bifrost
|
||||
# REQUIRED: Replace with a strong, randomly generated password
|
||||
# Example: Use `openssl rand -base64 32` to generate a secure password
|
||||
# Or set via Helm: --set postgresql.auth.password="$(openssl rand -base64 32)"
|
||||
password: "REPLACE_ME_WITH_STRONG_PASSWORD"
|
||||
database: bifrost
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 20Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
# Deploy Qdrant for vector store
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: qdrant
|
||||
qdrant:
|
||||
enabled: true
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
|
||||
# Enable semantic cache plugin to use Qdrant vector store
|
||||
plugins:
|
||||
semanticCache:
|
||||
enabled: true
|
||||
# OPTION 1 (Recommended): Reference to external Kubernetes Secret for OpenAI API key
|
||||
# Create the secret with: kubectl create secret generic bifrost-semantic-cache --from-literal=openai-key=sk-YOUR_OPENAI_KEY
|
||||
secretRef:
|
||||
name: "bifrost-semantic-cache"
|
||||
key: "openai-key"
|
||||
# OPTION 2 (Not recommended): Or uncomment to provide keys directly (not secure)
|
||||
# Remove secretRef above and uncomment the keys below:
|
||||
config:
|
||||
provider: "openai"
|
||||
# keys:
|
||||
# - "REPLACE_WITH_OPENAI_API_KEY" # Not recommended: use secretRef instead
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
75
helm-charts/bifrost/values-examples/postgres-redis.yaml
Normal file
75
helm-charts/bifrost/values-examples/postgres-redis.yaml
Normal file
@@ -0,0 +1,75 @@
|
||||
# Configuration: PostgreSQL for config/logs + Redis for vector store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/postgres-redis.yaml
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: postgres
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# Deploy PostgreSQL
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
username: bifrost
|
||||
password: bifrost_password
|
||||
database: bifrost
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
# Deploy Redis for vector store
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: redis
|
||||
redis:
|
||||
enabled: true
|
||||
auth:
|
||||
enabled: true
|
||||
password: "redis_password"
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 8Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
|
||||
# Enable semantic cache plugin to use Redis vector store
|
||||
plugins:
|
||||
semanticCache:
|
||||
enabled: true
|
||||
# Reference to external Kubernetes Secret for OpenAI API key
|
||||
# Create the secret with: kubectl create secret generic bifrost-semantic-cache --from-literal=openai-key=sk-YOUR_OPENAI_KEY
|
||||
secretRef:
|
||||
name: "bifrost-semantic-cache"
|
||||
key: "openai-key"
|
||||
config:
|
||||
provider: "openai"
|
||||
# keys are injected from the secret via environment variable
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
|
||||
72
helm-charts/bifrost/values-examples/postgres-weaviate.yaml
Normal file
72
helm-charts/bifrost/values-examples/postgres-weaviate.yaml
Normal file
@@ -0,0 +1,72 @@
|
||||
# Configuration: PostgreSQL for config/logs + Weaviate for vector store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/postgres-weaviate.yaml
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: postgres
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# Deploy PostgreSQL
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
username: bifrost
|
||||
password: bifrost_password
|
||||
database: bifrost
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
# Deploy Weaviate for vector store
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: weaviate
|
||||
weaviate:
|
||||
enabled: true
|
||||
replicas: 1
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
|
||||
# Enable semantic cache plugin to use vector store
|
||||
plugins:
|
||||
semanticCache:
|
||||
enabled: true
|
||||
# Reference to external Kubernetes Secret for OpenAI API key
|
||||
# Create the secret with: kubectl create secret generic bifrost-semantic-cache --from-literal=openai-key=sk-YOUR_OPENAI_KEY
|
||||
secretRef:
|
||||
name: "bifrost-semantic-cache"
|
||||
key: "openai-key"
|
||||
config:
|
||||
provider: "openai"
|
||||
# keys are injected from the secret via environment variable
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
|
||||
145
helm-charts/bifrost/values-examples/production-ha.yaml
Normal file
145
helm-charts/bifrost/values-examples/production-ha.yaml
Normal file
@@ -0,0 +1,145 @@
|
||||
# Configuration: Production High-Availability Setup
|
||||
# PostgreSQL + Weaviate + Auto-scaling + Ingress
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/production-ha.yaml
|
||||
|
||||
# Multiple replicas for HA
|
||||
replicaCount: 3
|
||||
|
||||
# Auto-scaling configuration
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 70
|
||||
targetMemoryUtilizationPercentage: 80
|
||||
|
||||
# Ingress configuration
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
hosts:
|
||||
- host: bifrost.yourdomain.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: bifrost-tls
|
||||
hosts:
|
||||
- bifrost.yourdomain.com
|
||||
|
||||
# Resource limits for production
|
||||
resources:
|
||||
limits:
|
||||
cpu: 4000m
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: postgres
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# PostgreSQL with higher resources
|
||||
postgresql:
|
||||
enabled: true
|
||||
auth:
|
||||
username: bifrost
|
||||
password: "CHANGE_ME_SECURE_PASSWORD"
|
||||
database: bifrost
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 50Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
# Weaviate for semantic caching
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: weaviate
|
||||
weaviate:
|
||||
enabled: true
|
||||
replicas: 2
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 50Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
# Bifrost production configuration
|
||||
bifrost:
|
||||
# Reference to external Kubernetes Secret for encryption key
|
||||
# Create the secret with: kubectl create secret generic bifrost-encryption --from-literal=key=YOUR_ENCRYPTION_KEY
|
||||
encryptionKeySecret:
|
||||
name: "bifrost-encryption"
|
||||
key: "key"
|
||||
|
||||
client:
|
||||
initialPoolSize: 1000
|
||||
allowedOrigins:
|
||||
- "https://yourdomain.com"
|
||||
- "https://app.yourdomain.com"
|
||||
enableLogging: true
|
||||
maxRequestBodySizeMb: 100
|
||||
|
||||
providers: {}
|
||||
# Add your production provider keys here
|
||||
|
||||
plugins:
|
||||
telemetry:
|
||||
enabled: true
|
||||
config: {}
|
||||
|
||||
logging:
|
||||
enabled: true
|
||||
config: {}
|
||||
|
||||
semanticCache:
|
||||
enabled: true
|
||||
# Reference to external Kubernetes Secret for OpenAI API key
|
||||
# Create the secret with: kubectl create secret generic bifrost-semantic-cache --from-literal=openai-key=sk-YOUR_OPENAI_KEY
|
||||
secretRef:
|
||||
name: "bifrost-semantic-cache"
|
||||
key: "openai-key"
|
||||
config:
|
||||
provider: "openai"
|
||||
# keys are injected from the secret via environment variable
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.85
|
||||
ttl: "1h"
|
||||
conversation_history_threshold: 5
|
||||
|
||||
# Pod affinity for better distribution
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app.kubernetes.io/name
|
||||
operator: In
|
||||
values:
|
||||
- bifrost
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
@@ -0,0 +1,621 @@
|
||||
# Configuration: Full Provider and Virtual Key Reference
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/providers-and-virtual-keys.yaml
|
||||
#
|
||||
# This example demonstrates configuration for every Bifrost-supported provider
|
||||
# (23 total) plus 7 virtual-key patterns covering different access-control needs:
|
||||
# - Simple API-key providers (openai, anthropic, cohere, groq, gemini, ...)
|
||||
# - Deployment-map providers (huggingface, replicate)
|
||||
# - URL-based / self-hosted providers (ollama, sgl, vllm)
|
||||
# - Cloud-native providers with nested config (azure, vertex, bedrock)
|
||||
#
|
||||
# Secrets are referenced via env.VAR_NAME (see ENVIRONMENT VARIABLES block
|
||||
# below). Provide them via extraEnv (map), env, envFrom, or a Kubernetes Secret
|
||||
# mounted on the pod — see values-examples/secrets-from-k8s.yaml for patterns.
|
||||
#
|
||||
# Field names follow transports/config.schema.json (the Bifrost runtime config
|
||||
# contract). VK provider_configs use the helm-native keys:[{name:...}] form,
|
||||
# which the helm chart template passes through to config.json.
|
||||
|
||||
# ==========================================================================
|
||||
# ENVIRONMENT VARIABLES REFERENCED
|
||||
# ==========================================================================
|
||||
# This file uses env.VAR_NAME for all secret values. Supply them via extraEnv
|
||||
# (map), env, envFrom, or an external secret store. Full list:
|
||||
#
|
||||
# Provider API keys:
|
||||
# OPENAI_API_KEY_1, OPENAI_API_KEY_2, OPENAI_API_KEY_3
|
||||
# ANTHROPIC_API_KEY_1, ANTHROPIC_API_KEY_2
|
||||
# GROQ_API_KEY_1, GROQ_API_KEY_2
|
||||
# COHERE_API_KEY, MISTRAL_API_KEY, GEMINI_API_KEY, OPENROUTER_API_KEY
|
||||
# PARASAIL_API_KEY, PERPLEXITY_API_KEY, CEREBRAS_API_KEY
|
||||
# ELEVENLABS_API_KEY, XAI_API_KEY, NEBIUS_API_KEY, FIREWORKS_API_KEY
|
||||
# RUNWAY_API_KEY, HUGGINGFACE_API_KEY, REPLICATE_API_KEY
|
||||
#
|
||||
# Azure:
|
||||
# AZURE_API_KEY, AZURE_ENDPOINT
|
||||
#
|
||||
# Vertex (Google Cloud):
|
||||
# VERTEX_PROJECT_ID, VERTEX_AUTH_CREDENTIALS (service-account key JSON)
|
||||
#
|
||||
# Bedrock (AWS) — choose static creds OR STS AssumeRole:
|
||||
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
|
||||
# AWS_ROLE_ARN, AWS_EXTERNAL_ID
|
||||
#
|
||||
# Self-hosted endpoints:
|
||||
# OLLAMA_URL, SGL_URL, VLLM_URL
|
||||
|
||||
# Image configuration
|
||||
image:
|
||||
repository: docker.io/maximhq/bifrost
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.3.55"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
# Service
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
|
||||
# Storage configuration - using SQLite for simplicity
|
||||
storage:
|
||||
mode: sqlite
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 5Gi
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# No PostgreSQL needed for this example
|
||||
postgresql:
|
||||
enabled: false
|
||||
|
||||
# No vector store for this example
|
||||
vectorStore:
|
||||
enabled: false
|
||||
type: none
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
appDir: /app/data
|
||||
port: 8080
|
||||
host: 0.0.0.0
|
||||
logLevel: info
|
||||
logStyle: json
|
||||
|
||||
client:
|
||||
dropExcessRequests: false
|
||||
initialPoolSize: 100
|
||||
allowedOrigins:
|
||||
- "*"
|
||||
enableLogging: true
|
||||
enforceGovernanceHeader: false
|
||||
allowDirectKeys: false
|
||||
maxRequestBodySizeMb: 100
|
||||
|
||||
# ==========================================================================
|
||||
# PROVIDERS
|
||||
# ==========================================================================
|
||||
# Every key entry supports the base fields:
|
||||
# name (required), value, weight (required), models, use_for_batch_api, aliases
|
||||
# Providers with nested configs add *_key_config blocks
|
||||
# (azure_key_config, vertex_key_config, bedrock_key_config, vllm_key_config,
|
||||
# ollama_key_config, sgl_key_config, replicate_key_config).
|
||||
|
||||
providers:
|
||||
# ------------------------------------------------------------------------
|
||||
# Simple API-key providers (base_key shape)
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# OpenAI — 3 keys with weighted load balancing.
|
||||
# openai-batch is flagged use_for_batch_api so it can serve the Batch API.
|
||||
openai:
|
||||
keys:
|
||||
- name: "openai-primary"
|
||||
value: "env.OPENAI_API_KEY_1"
|
||||
weight: 2 # 50% of traffic (2 of 4 total weight)
|
||||
models: ["*"]
|
||||
- name: "openai-secondary"
|
||||
value: "env.OPENAI_API_KEY_2"
|
||||
weight: 1 # 25%
|
||||
models: ["*"]
|
||||
- name: "openai-batch"
|
||||
value: "env.OPENAI_API_KEY_3"
|
||||
weight: 1 # 25%
|
||||
models: ["*"]
|
||||
use_for_batch_api: true # Allow Batch API with this key
|
||||
|
||||
# Anthropic — 2 keys, equal weight
|
||||
anthropic:
|
||||
keys:
|
||||
- name: "anthropic-primary"
|
||||
value: "env.ANTHROPIC_API_KEY_1"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
- name: "anthropic-secondary"
|
||||
value: "env.ANTHROPIC_API_KEY_2"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
# Groq — 2 keys
|
||||
groq:
|
||||
keys:
|
||||
- name: "groq-primary"
|
||||
value: "env.GROQ_API_KEY_1"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
- name: "groq-secondary"
|
||||
value: "env.GROQ_API_KEY_2"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
cohere:
|
||||
keys:
|
||||
- name: "cohere-main"
|
||||
value: "env.COHERE_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
mistral:
|
||||
keys:
|
||||
- name: "mistral-main"
|
||||
value: "env.MISTRAL_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
gemini:
|
||||
keys:
|
||||
- name: "gemini-main"
|
||||
value: "env.GEMINI_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
openrouter:
|
||||
keys:
|
||||
- name: "openrouter-main"
|
||||
value: "env.OPENROUTER_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
parasail:
|
||||
keys:
|
||||
- name: "parasail-main"
|
||||
value: "env.PARASAIL_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
perplexity:
|
||||
keys:
|
||||
- name: "perplexity-main"
|
||||
value: "env.PERPLEXITY_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
cerebras:
|
||||
keys:
|
||||
- name: "cerebras-main"
|
||||
value: "env.CEREBRAS_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
elevenlabs:
|
||||
keys:
|
||||
- name: "elevenlabs-main"
|
||||
value: "env.ELEVENLABS_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
xai:
|
||||
keys:
|
||||
- name: "xai-main"
|
||||
value: "env.XAI_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
nebius:
|
||||
keys:
|
||||
- name: "nebius-main"
|
||||
value: "env.NEBIUS_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
fireworks:
|
||||
keys:
|
||||
- name: "fireworks-main"
|
||||
value: "env.FIREWORKS_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
runway:
|
||||
keys:
|
||||
- name: "runway-main"
|
||||
value: "env.RUNWAY_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Deployment-map providers (use `aliases` to map logical -> provider IDs)
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
huggingface:
|
||||
keys:
|
||||
- name: "huggingface-main"
|
||||
value: "env.HUGGINGFACE_API_KEY"
|
||||
weight: 1
|
||||
models: ["llama-3", "mixtral"]
|
||||
aliases:
|
||||
# Logical model name -> HF repo path used when invoking
|
||||
llama-3: "meta-llama/Meta-Llama-3-8B-Instruct"
|
||||
mixtral: "mistralai/Mixtral-8x7B-Instruct-v0.1"
|
||||
|
||||
replicate:
|
||||
keys:
|
||||
- name: "replicate-main"
|
||||
value: "env.REPLICATE_API_KEY"
|
||||
weight: 1
|
||||
models: ["llama-3"]
|
||||
aliases:
|
||||
llama-3: "meta/meta-llama-3-70b-instruct"
|
||||
replicate_key_config:
|
||||
use_deployments_endpoint: false # false = /models endpoint (default)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# URL-based / self-hosted providers
|
||||
# ------------------------------------------------------------------------
|
||||
# These providers talk to an HTTP endpoint you operate yourself. They do
|
||||
# not typically require API keys (value stays empty).
|
||||
|
||||
ollama:
|
||||
keys:
|
||||
- name: "ollama-main"
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
ollama_key_config:
|
||||
url: "env.OLLAMA_URL" # e.g. http://ollama.svc.cluster.local:11434
|
||||
|
||||
sgl:
|
||||
keys:
|
||||
- name: "sgl-main"
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
sgl_key_config:
|
||||
url: "env.SGL_URL" # e.g. http://sgl-router.svc.cluster.local:30000
|
||||
|
||||
vllm:
|
||||
# vLLM instances are model-specific: one key per served model.
|
||||
keys:
|
||||
- name: "vllm-llama3-70b"
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["llama-3-70b"]
|
||||
vllm_key_config:
|
||||
url: "env.VLLM_URL" # e.g. http://vllm.svc.cluster.local:8000
|
||||
model_name: "meta-llama/Meta-Llama-3-70B-Instruct"
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Cloud-native providers (nested provider-specific config)
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Azure OpenAI — two auth modes:
|
||||
# 1. azure-apikey: explicit API key (via env var).
|
||||
# 2. azure-managed-identity: inherits credentials via DefaultAzureCredential
|
||||
# when `value` is empty. Covers managed identity
|
||||
# on Azure VMs / AKS workload identity / env vars
|
||||
# (AZURE_CLIENT_ID etc.) / Azure CLI (dev).
|
||||
# (Service-principal client_id/client_secret/tenant_id fields exist in the
|
||||
# runtime code but aren't exposed in the current schema — use env-based
|
||||
# DefaultAzureCredential instead.)
|
||||
azure:
|
||||
keys:
|
||||
- name: "azure-apikey"
|
||||
value: "env.AZURE_API_KEY"
|
||||
weight: 1
|
||||
models: ["gpt-4o", "gpt-4o-mini", "text-embedding-3-small"]
|
||||
azure_key_config:
|
||||
endpoint: "env.AZURE_ENDPOINT" # e.g. https://my-resource.openai.azure.com
|
||||
api_version: "2024-10-21"
|
||||
deployments:
|
||||
# Logical model name -> Azure deployment name
|
||||
gpt-4o: "gpt-4o-prod"
|
||||
gpt-4o-mini: "gpt-4o-mini-prod"
|
||||
text-embedding-3-small: "embeddings-prod"
|
||||
- name: "azure-managed-identity"
|
||||
# Pure identity inheritance: empty `value` triggers DefaultAzureCredential.
|
||||
# Works out-of-the-box on AKS with workload identity, Azure VMs with
|
||||
# system/user-assigned managed identity, or local dev via `az login`.
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["gpt-4o"]
|
||||
azure_key_config:
|
||||
endpoint: "env.AZURE_ENDPOINT"
|
||||
api_version: "2024-10-21"
|
||||
deployments:
|
||||
gpt-4o: "gpt-4o-prod"
|
||||
|
||||
# Google Vertex AI — two auth modes:
|
||||
# 1. vertex-sa-key: explicit service-account key JSON via env var.
|
||||
# 2. vertex-workload-id: inherits credentials from the environment
|
||||
# (GKE Workload Identity, GCE metadata server,
|
||||
# or GOOGLE_APPLICATION_CREDENTIALS path). Omit
|
||||
# `auth_credentials` and the Google SDK calls
|
||||
# google.FindDefaultCredentials automatically.
|
||||
vertex:
|
||||
keys:
|
||||
- name: "vertex-sa-key"
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
vertex_key_config:
|
||||
project_id: "env.VERTEX_PROJECT_ID"
|
||||
region: "us-central1"
|
||||
auth_credentials: "env.VERTEX_AUTH_CREDENTIALS"
|
||||
# project_number: "env.VERTEX_PROJECT_NUMBER" # optional
|
||||
- name: "vertex-workload-id"
|
||||
# Pure ADC inheritance: works on GKE with Workload Identity, GCE
|
||||
# VMs, Cloud Run, or local dev via `gcloud auth application-default login`.
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
vertex_key_config:
|
||||
project_id: "env.VERTEX_PROJECT_ID"
|
||||
region: "us-central1"
|
||||
# auth_credentials intentionally omitted -> ADC lookup
|
||||
|
||||
# AWS Bedrock — three auth modes:
|
||||
# 1. bedrock-static: explicit AWS access/secret keys + S3 batch bucket
|
||||
# 2. bedrock-irsa: inherits pod/EKS credentials (IRSA, EC2 instance
|
||||
# profile, env vars, ~/.aws/credentials) — set only
|
||||
# `region`; the AWS SDK default credential chain
|
||||
# resolves the rest.
|
||||
# 3. bedrock-assumerole: STS AssumeRole chained on top of the default
|
||||
# chain — inherits *source* creds from the pod,
|
||||
# then assumes a cross-account role.
|
||||
bedrock:
|
||||
keys:
|
||||
- name: "bedrock-static"
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
bedrock_key_config:
|
||||
region: "us-east-1"
|
||||
access_key: "env.AWS_ACCESS_KEY_ID"
|
||||
secret_key: "env.AWS_SECRET_ACCESS_KEY"
|
||||
deployments:
|
||||
# Logical model -> Bedrock inference profile
|
||||
anthropic.claude-3-5-sonnet: "us.anthropic.claude-3-5-sonnet-20240620-v1:0"
|
||||
batch_s3_config:
|
||||
buckets:
|
||||
- bucket_name: "my-bedrock-batch-bucket"
|
||||
prefix: "batch/"
|
||||
is_default: true
|
||||
- name: "bedrock-irsa"
|
||||
# Pure credential inheritance: works out-of-the-box on EKS with IRSA,
|
||||
# on EC2 with an instance profile, or with AWS_* env vars present.
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
bedrock_key_config:
|
||||
region: "us-east-1"
|
||||
# access_key / secret_key intentionally omitted -> SDK default chain
|
||||
- name: "bedrock-assumerole"
|
||||
value: ""
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
bedrock_key_config:
|
||||
region: "us-west-2"
|
||||
# No static creds -> source identity comes from pod's default chain.
|
||||
role_arn: "env.AWS_ROLE_ARN"
|
||||
external_id: "env.AWS_EXTERNAL_ID"
|
||||
session_name: "bifrost-session"
|
||||
|
||||
# ==========================================================================
|
||||
# GOVERNANCE — budgets, rate limits, and virtual keys
|
||||
# ==========================================================================
|
||||
|
||||
governance:
|
||||
# --------------------------------------------------------------------
|
||||
# Budgets — spending caps per period
|
||||
# --------------------------------------------------------------------
|
||||
budgets:
|
||||
- id: "budget-dev"
|
||||
max_limit: 50 # $50
|
||||
reset_duration: "1M" # monthly
|
||||
- id: "budget-production"
|
||||
max_limit: 500 # $500
|
||||
reset_duration: "1M"
|
||||
- id: "budget-testing"
|
||||
max_limit: 10 # $10
|
||||
reset_duration: "1d" # daily
|
||||
- id: "budget-team-platform"
|
||||
max_limit: 2000 # $2000 — larger team/platform budget
|
||||
reset_duration: "1M"
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Rate limits — token + request caps per period
|
||||
# --------------------------------------------------------------------
|
||||
rateLimits:
|
||||
- id: "rate-limit-standard"
|
||||
token_max_limit: 100000
|
||||
token_reset_duration: "1h"
|
||||
request_max_limit: 1000
|
||||
request_reset_duration: "1h"
|
||||
- id: "rate-limit-high"
|
||||
token_max_limit: 500000
|
||||
token_reset_duration: "1h"
|
||||
request_max_limit: 5000
|
||||
request_reset_duration: "1h"
|
||||
- id: "rate-limit-testing"
|
||||
token_max_limit: 10000
|
||||
token_reset_duration: "1h"
|
||||
request_max_limit: 100
|
||||
request_reset_duration: "1h"
|
||||
- id: "rate-limit-burst"
|
||||
token_max_limit: 50000
|
||||
token_reset_duration: "1m" # Short-window burst cap
|
||||
request_max_limit: 500
|
||||
request_reset_duration: "1m"
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Virtual keys — access tokens scoped to providers/models/keys
|
||||
# --------------------------------------------------------------------
|
||||
# provider_configs[].keys scopes the VK to specific provider keys by name.
|
||||
# Omit provider_configs to grant access to every provider.
|
||||
# Omit keys inside a provider_config to allow all keys for that provider.
|
||||
|
||||
virtualKeys:
|
||||
# 1. Dev key — access to every provider, no restrictions.
|
||||
- id: "vk-all-providers-dev"
|
||||
name: "Dev: all providers"
|
||||
is_active: true
|
||||
budget_id: "budget-dev"
|
||||
rate_limit_id: "rate-limit-standard"
|
||||
# No provider_configs -> all providers accessible
|
||||
|
||||
# 2. OpenAI only — restricted to 2 keys and 2 models.
|
||||
- id: "vk-openai-scoped"
|
||||
name: "OpenAI only (scoped)"
|
||||
is_active: true
|
||||
budget_id: "budget-production"
|
||||
rate_limit_id: "rate-limit-high"
|
||||
provider_configs:
|
||||
- provider: "openai"
|
||||
weight: 1
|
||||
allowed_models: ["gpt-4o", "gpt-4o-mini"]
|
||||
keys:
|
||||
- name: "openai-primary"
|
||||
- name: "openai-secondary"
|
||||
|
||||
# 3. Multi-provider — weighted routing across OpenAI/Anthropic/Groq.
|
||||
# OpenAI gets 50% (weight 2), the others 25% each (weight 1).
|
||||
- id: "vk-multi-provider"
|
||||
name: "Multi-provider weighted"
|
||||
is_active: true
|
||||
budget_id: "budget-production"
|
||||
rate_limit_id: "rate-limit-high"
|
||||
provider_configs:
|
||||
- provider: "openai"
|
||||
weight: 2
|
||||
allowed_models: ["*"]
|
||||
# Omitting keys -> all openai keys allowed
|
||||
- provider: "anthropic"
|
||||
weight: 1
|
||||
allowed_models: ["*"]
|
||||
keys:
|
||||
- name: "anthropic-primary"
|
||||
- provider: "groq"
|
||||
weight: 1
|
||||
allowed_models: ["*"]
|
||||
|
||||
# 4. Cloud providers — Azure + Vertex + Bedrock only.
|
||||
# Shows that VK scoping is identical regardless of nested key_config.
|
||||
- id: "vk-cloud-providers"
|
||||
name: "Cloud providers (Azure/Vertex/Bedrock)"
|
||||
is_active: true
|
||||
budget_id: "budget-team-platform"
|
||||
rate_limit_id: "rate-limit-high"
|
||||
provider_configs:
|
||||
- provider: "azure"
|
||||
weight: 1
|
||||
keys:
|
||||
- name: "azure-apikey"
|
||||
- name: "azure-managed-identity"
|
||||
- provider: "vertex"
|
||||
weight: 1
|
||||
keys:
|
||||
- name: "vertex-sa-key"
|
||||
- name: "vertex-workload-id"
|
||||
- provider: "bedrock"
|
||||
weight: 1
|
||||
keys:
|
||||
- name: "bedrock-static"
|
||||
- name: "bedrock-irsa"
|
||||
- name: "bedrock-assumerole"
|
||||
|
||||
# 5. Self-hosted — Ollama + vLLM + SGL only.
|
||||
# Low budget because self-hosted inference is ~free.
|
||||
- id: "vk-self-hosted"
|
||||
name: "Self-hosted (Ollama/vLLM/SGL)"
|
||||
is_active: true
|
||||
budget_id: "budget-dev"
|
||||
rate_limit_id: "rate-limit-high"
|
||||
provider_configs:
|
||||
- provider: "ollama"
|
||||
weight: 1
|
||||
- provider: "vllm"
|
||||
weight: 1
|
||||
- provider: "sgl"
|
||||
weight: 1
|
||||
|
||||
# 6. Testing — tight budget, tight rate limit, single model, single key.
|
||||
- id: "vk-testing-limited"
|
||||
name: "Testing (gpt-4o-mini only)"
|
||||
is_active: true
|
||||
budget_id: "budget-testing"
|
||||
rate_limit_id: "rate-limit-testing"
|
||||
provider_configs:
|
||||
- provider: "openai"
|
||||
weight: 1
|
||||
allowed_models: ["gpt-4o-mini"]
|
||||
keys:
|
||||
- name: "openai-secondary"
|
||||
|
||||
# 7. Batch API — restricted to keys flagged use_for_batch_api: true.
|
||||
# Pairs with the openai-batch key above. Burst rate-limit for batch flushes.
|
||||
- id: "vk-batch-api"
|
||||
name: "Batch API workloads"
|
||||
is_active: true
|
||||
budget_id: "budget-production"
|
||||
rate_limit_id: "rate-limit-burst"
|
||||
provider_configs:
|
||||
- provider: "openai"
|
||||
weight: 1
|
||||
allowed_models: ["*"]
|
||||
keys:
|
||||
- name: "openai-batch"
|
||||
|
||||
# Plugins configuration
|
||||
plugins:
|
||||
telemetry:
|
||||
enabled: false
|
||||
logging:
|
||||
enabled: true
|
||||
config: {}
|
||||
governance:
|
||||
enabled: true
|
||||
config:
|
||||
is_vk_mandatory: false # Set to true to require virtual key on all requests
|
||||
|
||||
# Resource limits
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
# Probes
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
110
helm-charts/bifrost/values-examples/secrets-from-k8s.yaml
Normal file
110
helm-charts/bifrost/values-examples/secrets-from-k8s.yaml
Normal file
@@ -0,0 +1,110 @@
|
||||
# Configuration: Using Kubernetes Secrets for All Sensitive Values
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/secrets-from-k8s.yaml
|
||||
#
|
||||
# This example demonstrates how to use existing Kubernetes secrets for all
|
||||
# sensitive values instead of putting them directly in the values file.
|
||||
#
|
||||
# Prerequisites:
|
||||
# 1. Create the required Kubernetes secrets before installing the chart:
|
||||
#
|
||||
# # PostgreSQL password secret
|
||||
# kubectl create secret generic postgres-credentials \
|
||||
# --from-literal=password='your-postgres-password'
|
||||
#
|
||||
# # Encryption key secret
|
||||
# kubectl create secret generic bifrost-encryption \
|
||||
# --from-literal=key='your-encryption-key'
|
||||
#
|
||||
# # Provider API keys secret
|
||||
# kubectl create secret generic provider-api-keys \
|
||||
# --from-literal=openai-api-key='sk-...' \
|
||||
# --from-literal=anthropic-api-key='sk-ant-...'
|
||||
#
|
||||
# # Qdrant API key secret (if using Qdrant)
|
||||
# kubectl create secret generic qdrant-credentials \
|
||||
# --from-literal=api-key='your-qdrant-api-key'
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: postgres
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# External PostgreSQL with credentials from Kubernetes secret
|
||||
postgresql:
|
||||
enabled: false
|
||||
external:
|
||||
enabled: true
|
||||
host: "your-postgres-host.example.com"
|
||||
port: 5432
|
||||
user: bifrost
|
||||
database: bifrost
|
||||
sslMode: require
|
||||
# Reference existing Kubernetes secret for password
|
||||
existingSecret: "postgres-credentials"
|
||||
passwordKey: "password"
|
||||
|
||||
# Vector store with API key from Kubernetes secret
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: qdrant
|
||||
qdrant:
|
||||
enabled: false
|
||||
external:
|
||||
enabled: true
|
||||
host: "your-qdrant-host.example.com"
|
||||
port: 6334
|
||||
useTls: true
|
||||
# Reference existing Kubernetes secret for API key
|
||||
existingSecret: "qdrant-credentials"
|
||||
apiKeyKey: "api-key"
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
# Encryption key from Kubernetes secret
|
||||
encryptionKeySecret:
|
||||
name: "bifrost-encryption"
|
||||
key: "key"
|
||||
|
||||
client:
|
||||
enableLogging: true
|
||||
|
||||
# Provider configurations using env.VAR_NAME syntax
|
||||
# The actual values come from providerSecrets below
|
||||
providers:
|
||||
openai:
|
||||
keys:
|
||||
- name: "openai-primary"
|
||||
value: "env.OPENAI_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
anthropic:
|
||||
keys:
|
||||
- name: "anthropic-primary"
|
||||
value: "env.ANTHROPIC_API_KEY"
|
||||
weight: 1
|
||||
models: ["*"]
|
||||
|
||||
# Provider secrets - inject API keys from Kubernetes secrets as env vars
|
||||
providerSecrets:
|
||||
openai:
|
||||
existingSecret: "provider-api-keys"
|
||||
key: "openai-api-key"
|
||||
envVar: "OPENAI_API_KEY"
|
||||
anthropic:
|
||||
existingSecret: "provider-api-keys"
|
||||
key: "anthropic-api-key"
|
||||
envVar: "ANTHROPIC_API_KEY"
|
||||
|
||||
plugins:
|
||||
# Maxim plugin with API key from secret
|
||||
maxim:
|
||||
enabled: false # Set to true if using Maxim
|
||||
config:
|
||||
log_repo_id: "your-log-repo-id"
|
||||
secretRef:
|
||||
name: "maxim-credentials"
|
||||
key: "api-key"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# Example Kubernetes Secret for Semantic Cache API Key
|
||||
# This secret is referenced by production-ha.yaml
|
||||
#
|
||||
# IMPORTANT: Do not commit this file with real API keys to version control!
|
||||
#
|
||||
# Usage:
|
||||
# 1. Replace 'YOUR_OPENAI_API_KEY' with your actual OpenAI API key
|
||||
# 2. Apply the secret: kubectl apply -f semantic-cache-secret-example.yaml -n <namespace>
|
||||
# 3. Deploy Bifrost with: helm install bifrost . -f values-examples/production-ha.yaml -n <namespace>
|
||||
#
|
||||
# Alternative: Create the secret using kubectl command:
|
||||
# kubectl create secret generic bifrost-semantic-cache \
|
||||
# --from-literal=openai-key=sk-YOUR_OPENAI_API_KEY \
|
||||
# -n <namespace>
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: bifrost-semantic-cache
|
||||
namespace: default # Change this to your target namespace
|
||||
labels:
|
||||
app.kubernetes.io/name: bifrost
|
||||
app.kubernetes.io/component: semantic-cache
|
||||
type: Opaque
|
||||
stringData:
|
||||
# Replace with your actual OpenAI API key
|
||||
openai-key: "sk-YOUR_OPENAI_API_KEY"
|
||||
|
||||
34
helm-charts/bifrost/values-examples/sqlite-only.yaml
Normal file
34
helm-charts/bifrost/values-examples/sqlite-only.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
# Configuration: SQLite for config and logs store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/sqlite-only.yaml
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: sqlite
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# No PostgreSQL
|
||||
postgresql:
|
||||
enabled: false
|
||||
|
||||
# No vector store
|
||||
vectorStore:
|
||||
enabled: false
|
||||
type: none
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
# openai:
|
||||
# keys:
|
||||
# - value: "sk-..."
|
||||
# weight: 1
|
||||
|
||||
58
helm-charts/bifrost/values-examples/sqlite-qdrant.yaml
Normal file
58
helm-charts/bifrost/values-examples/sqlite-qdrant.yaml
Normal file
@@ -0,0 +1,58 @@
|
||||
# Configuration: SQLite for config/logs + Qdrant for vector store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/sqlite-qdrant.yaml
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: sqlite
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# No PostgreSQL
|
||||
postgresql:
|
||||
enabled: false
|
||||
|
||||
# Deploy Qdrant for vector store
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: qdrant
|
||||
qdrant:
|
||||
enabled: true
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
|
||||
# Enable semantic cache plugin to use vector store
|
||||
plugins:
|
||||
semanticCache:
|
||||
enabled: true
|
||||
# Reference to external Kubernetes Secret for OpenAI API key
|
||||
# Create the secret with: kubectl create secret generic bifrost-semantic-cache --from-literal=openai-key=sk-YOUR_OPENAI_KEY
|
||||
secretRef:
|
||||
name: "bifrost-semantic-cache"
|
||||
key: "openai-key"
|
||||
config:
|
||||
provider: "openai"
|
||||
# keys are injected from the secret via environment variable
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
76
helm-charts/bifrost/values-examples/sqlite-redis.yaml
Normal file
76
helm-charts/bifrost/values-examples/sqlite-redis.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
# Configuration: SQLite for config/logs + Redis for vector store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/sqlite-redis.yaml
|
||||
#
|
||||
# SECURITY NOTE: This example contains placeholder values that MUST be replaced
|
||||
# before deployment. Specifically:
|
||||
# - Redis password must be set to a strong, randomly generated value
|
||||
# - Provider API keys must be replaced with real keys
|
||||
# See inline comments for specific requirements.
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: sqlite
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# No PostgreSQL
|
||||
postgresql:
|
||||
enabled: false
|
||||
|
||||
# Deploy Redis for vector store
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: redis
|
||||
redis:
|
||||
enabled: true
|
||||
auth:
|
||||
enabled: true
|
||||
# REQUIRED: Replace with a strong, randomly generated password
|
||||
# Example: Use `openssl rand -base64 32` to generate a secure password
|
||||
# Or set via Helm: --set vectorStore.redis.auth.password="$(openssl rand -base64 32)"
|
||||
# Or use a Kubernetes secret: --set vectorStore.redis.auth.existingSecret=redis-secret
|
||||
password: "REPLACE_ME_WITH_STRONG_PASSWORD"
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 8Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
|
||||
# Enable semantic cache plugin to use Redis vector store
|
||||
plugins:
|
||||
semanticCache:
|
||||
enabled: true
|
||||
# OPTION 1 (Recommended): Reference to external Kubernetes Secret for OpenAI API key
|
||||
# Create the secret with: kubectl create secret generic bifrost-semantic-cache --from-literal=openai-key=sk-YOUR_OPENAI_KEY
|
||||
secretRef:
|
||||
name: "bifrost-semantic-cache"
|
||||
key: "openai-key"
|
||||
# OPTION 2 (Not recommended): Or uncomment to provide keys directly (not secure)
|
||||
# Remove secretRef above and uncomment the keys below:
|
||||
config:
|
||||
provider: "openai"
|
||||
# keys:
|
||||
# - "REPLACE_WITH_OPENAI_API_KEY" # Not recommended: use secretRef instead
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
|
||||
60
helm-charts/bifrost/values-examples/sqlite-weaviate.yaml
Normal file
60
helm-charts/bifrost/values-examples/sqlite-weaviate.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
# Configuration: SQLite for config/logs + Weaviate for vector store
|
||||
# Usage: helm install bifrost ./bifrost -f values-examples/sqlite-weaviate.yaml
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
mode: sqlite
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
configStore:
|
||||
enabled: true
|
||||
logsStore:
|
||||
enabled: true
|
||||
|
||||
# No PostgreSQL
|
||||
postgresql:
|
||||
enabled: false
|
||||
|
||||
# Deploy Weaviate for vector store
|
||||
vectorStore:
|
||||
enabled: true
|
||||
type: weaviate
|
||||
weaviate:
|
||||
enabled: true
|
||||
replicas: 1
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
# Bifrost configuration
|
||||
bifrost:
|
||||
client:
|
||||
enableLogging: true
|
||||
providers: {}
|
||||
# Add your provider keys here
|
||||
|
||||
# Enable semantic cache plugin to use vector store
|
||||
plugins:
|
||||
semanticCache:
|
||||
enabled: true
|
||||
# Reference to external Kubernetes Secret for OpenAI API key
|
||||
# Create the secret with: kubectl create secret generic bifrost-semantic-cache --from-literal=openai-key=sk-YOUR_OPENAI_KEY
|
||||
secretRef:
|
||||
name: "bifrost-semantic-cache"
|
||||
key: "openai-key"
|
||||
config:
|
||||
provider: "openai"
|
||||
# keys are injected from the secret via environment variable
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
|
||||
3466
helm-charts/bifrost/values.schema.json
Normal file
3466
helm-charts/bifrost/values.schema.json
Normal file
File diff suppressed because it is too large
Load Diff
949
helm-charts/bifrost/values.yaml
Normal file
949
helm-charts/bifrost/values.yaml
Normal file
@@ -0,0 +1,949 @@
|
||||
# Default values for Bifrost
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
# Bifrost application configuration
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
# Container image repository
|
||||
# Default: Docker Hub public image
|
||||
# For enterprise customers with private registry, use full URL:
|
||||
# repository: us-west1-docker.pkg.dev/bifrost-enterprise/your-org/bifrost
|
||||
# repository: your-registry.example.com/your-org/bifrost
|
||||
# repository: 123456789.dkr.ecr.us-east-1.amazonaws.com/bifrost
|
||||
repository: docker.io/maximhq/bifrost
|
||||
pullPolicy: IfNotPresent
|
||||
# REQUIRED: Specify the image tag (e.g., v1.5.0, latest)
|
||||
# Docker images are tagged with v prefix (e.g., v1.5.0)
|
||||
# See available tags at: https://hub.docker.com/r/maximhq/bifrost/tags
|
||||
tag: ""
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# Automatically mount a ServiceAccount's API credentials?
|
||||
automount: true
|
||||
# Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
# Annotations to add to the deployment metadata
|
||||
# Useful for tools like Keel (keel.sh) for automatic image updates
|
||||
# Example:
|
||||
# deploymentAnnotations:
|
||||
# keel.sh/policy: force
|
||||
# keel.sh/trigger: poll
|
||||
deploymentAnnotations: {}
|
||||
|
||||
# Labels to add to the deployment metadata (in addition to default labels)
|
||||
deploymentLabels: {}
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
fsGroup: 1000
|
||||
runAsUser: 1000
|
||||
runAsNonRoot: true
|
||||
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
annotations: {}
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts:
|
||||
- host: bifrost.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls: []
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 80
|
||||
targetMemoryUtilizationPercentage: 80
|
||||
# HPA scaling behavior configuration
|
||||
# Controls how quickly the HPA scales up/down to prevent connection disruption
|
||||
behavior:
|
||||
scaleDown:
|
||||
# Stabilization window prevents rapid scale-down oscillation.
|
||||
# The HPA will wait this long after the last scale event before scaling down again.
|
||||
# Important for long-lived streaming connections (e.g. SSE for LLM inference).
|
||||
stabilizationWindowSeconds: 300
|
||||
policies:
|
||||
- type: Pods
|
||||
value: 1
|
||||
periodSeconds: 120
|
||||
scaleUp:
|
||||
stabilizationWindowSeconds: 30
|
||||
|
||||
# Additional volumes on the output Deployment definition.
|
||||
volumes: []
|
||||
|
||||
# Additional volumeMounts on the output Deployment definition.
|
||||
volumeMounts: []
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
# Graceful shutdown configuration for long-lived connections (SSE streaming)
|
||||
# When a pod is terminated (e.g. during HPA scale-down), active streaming connections
|
||||
# are severed abruptly. This causes clients to lose their SSE stream mid-response.
|
||||
# The preStop hook and termination grace period give in-flight requests time to complete.
|
||||
terminationGracePeriodSeconds: 60
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
# Sleep allows the pod to be removed from the Service endpoints and load balancer
|
||||
# before the process starts shutting down, preventing new connections from arriving
|
||||
# while existing ones drain.
|
||||
command: ["sh", "-c", "sleep 15"]
|
||||
|
||||
# Bifrost specific configuration
|
||||
# You can find entire schema at https://getbifrost.ai/schema
|
||||
bifrost:
|
||||
# Application settings
|
||||
appDir: /app/data
|
||||
port: 8080
|
||||
host: 0.0.0.0
|
||||
logLevel: info
|
||||
logStyle: json
|
||||
|
||||
# Encryption key for sensitive data
|
||||
# Can be set as a secret or environment variable
|
||||
encryptionKey: ""
|
||||
|
||||
# Use an existing Kubernetes secret for the encryption key.
|
||||
# When `name` is set, takes precedence over `encryptionKey`: the chart
|
||||
# injects BIFROST_ENCRYPTION_KEY into the pod via secretKeyRef and writes
|
||||
# `encryption_key: "env.BIFROST_ENCRYPTION_KEY"` in the rendered config.json.
|
||||
encryptionKeySecret:
|
||||
name: ""
|
||||
key: "encryption-key"
|
||||
|
||||
# Authentication configuration (top-level)
|
||||
# This controls authentication for Bifrost API and dashboard
|
||||
authConfig:
|
||||
adminUsername: ""
|
||||
adminPassword: ""
|
||||
isEnabled: false
|
||||
disableAuthOnInference: false
|
||||
# Use existing Kubernetes secret for admin credentials
|
||||
existingSecret: ""
|
||||
usernameKey: "username"
|
||||
passwordKey: "password"
|
||||
|
||||
# Client configuration
|
||||
client:
|
||||
dropExcessRequests: false
|
||||
initialPoolSize: 300
|
||||
allowedOrigins:
|
||||
- "*"
|
||||
enableLogging: true
|
||||
disableContentLogging: false
|
||||
disableDbPingsInHealth: false
|
||||
logRetentionDays: 365
|
||||
enforceGovernanceHeader: false
|
||||
allowDirectKeys: false
|
||||
maxRequestBodySizeMb: 100
|
||||
compat:
|
||||
convertTextToChat: false
|
||||
convertChatToResponses: false
|
||||
shouldDropParams: false
|
||||
shouldConvertParams: false
|
||||
prometheusLabels: []
|
||||
# Header filtering configuration for x-bf-eh-* headers forwarded to LLM providers
|
||||
headerFilterConfig:
|
||||
allowlist: []
|
||||
denylist: []
|
||||
# asyncJobResultTTL: 3600 # Default TTL for async job results in seconds
|
||||
# requiredHeaders: [] # Headers that must be present on every request
|
||||
# loggingHeaders: [] # Headers to capture in log metadata
|
||||
# allowedHeaders: [] # Additional allowed headers for CORS and WebSocket
|
||||
# mcpAgentDepth: 10 # Maximum depth for MCP agent mode tool execution
|
||||
# mcpToolExecutionTimeout: 30 # Timeout for individual MCP tool execution in seconds
|
||||
# mcpCodeModeBindingLevel: "" # Code mode binding level (server or tool)
|
||||
# mcpToolSyncInterval: 0 # Global tool sync interval in minutes (0 = disabled)
|
||||
# hideDeletedVirtualKeysInFilters: false # Omit deleted virtual keys from logs/MCP filter data
|
||||
# whitelistedRoutes: [] # Routes that bypass auth middleware
|
||||
# routingChainMaxDepth: 10 # Maximum depth for routing rule chain evaluation
|
||||
|
||||
# Framework configuration
|
||||
framework:
|
||||
pricing:
|
||||
# Custom pricing URL for model cost data
|
||||
pricingUrl: ""
|
||||
# Sync interval in seconds (default: 86400 = 24 hours, minimum: 3600)
|
||||
pricingSyncInterval: 86400
|
||||
|
||||
# Provider configurations (add your provider keys here)
|
||||
# You can specify API keys directly or use env.VAR_NAME syntax to reference environment variables
|
||||
# When using existingSecret in providerSecrets, the keys will be injected as env vars and
|
||||
# you should use env.VAR_NAME syntax in the value field
|
||||
# Note: The entire providers block is passed through to the config as-is.
|
||||
# See https://getbifrost.ai/schema for the full provider schema.
|
||||
providers: {}
|
||||
# openai:
|
||||
# keys:
|
||||
# - name: "primary-key" # Key name (required, must be unique)
|
||||
# value: "sk-..." # Direct value
|
||||
# weight: 1
|
||||
# models: ["gpt-4o", "gpt-4o-mini"] # Restrict key to specific models
|
||||
# use_for_batch_api: false # Whether this key can be used for batch API
|
||||
# - name: "secondary-key"
|
||||
# value: "env.OPENAI_KEY" # Reference to environment variable
|
||||
# weight: 1
|
||||
# # Network configuration (optional, per-provider)
|
||||
# network_config:
|
||||
# base_url: "" # Custom base URL (required for Ollama)
|
||||
# extra_headers: {} # Additional headers to send with requests
|
||||
# default_request_timeout_in_seconds: 300 # Request timeout
|
||||
# max_retries: 3 # Maximum number of retries
|
||||
# retry_backoff_initial_ms: 500 # Initial retry backoff in ms
|
||||
# retry_backoff_max_ms: 5000 # Max retry backoff in ms
|
||||
# stream_idle_timeout_in_seconds: 60 # Max wait for next stream chunk (default: 60)
|
||||
# max_conns_per_host: 5000 # Max TCP connections per host (default: 5000)
|
||||
# beta_header_overrides: # Override Anthropic beta header support (optional)
|
||||
# redact-thinking-: true # Enable/disable specific beta headers by prefix
|
||||
# # Concurrency configuration (optional)
|
||||
# concurrency_and_buffer_size:
|
||||
# concurrency: 100 # Number of concurrent requests
|
||||
# buffer_size: 200 # Buffer size for requests
|
||||
# # Proxy configuration (optional)
|
||||
# proxy_config:
|
||||
# type: "none" # Options: none, http, socks5, environment
|
||||
# url: ""
|
||||
# username: ""
|
||||
# password: ""
|
||||
# ca_cert_pem: "" # PEM-encoded CA cert for SSL-intercepting proxies
|
||||
# send_back_raw_response: false # Include raw response in BifrostResponse
|
||||
# store_raw_request_response: false # Capture raw payloads for plugins only; not returned to client
|
||||
#
|
||||
# anthropic:
|
||||
# keys:
|
||||
# - name: "anthropic-key"
|
||||
# value: "sk-ant-..."
|
||||
# weight: 1
|
||||
#
|
||||
# # Azure OpenAI example (requires azure_key_config)
|
||||
# azure:
|
||||
# keys:
|
||||
# - name: "azure-key"
|
||||
# value: "..."
|
||||
# weight: 1
|
||||
# azure_key_config:
|
||||
# endpoint: "https://your-resource.openai.azure.com"
|
||||
# api_version: "2024-02-15-preview"
|
||||
# deployments:
|
||||
# gpt-4o: "my-gpt4o-deployment"
|
||||
#
|
||||
# # Google Vertex AI example (requires vertex_key_config)
|
||||
# vertex:
|
||||
# keys:
|
||||
# - name: "vertex-key"
|
||||
# value: ""
|
||||
# weight: 1
|
||||
# vertex_key_config:
|
||||
# project_id: "my-gcp-project"
|
||||
# region: "us-central1"
|
||||
# auth_credentials: "env.GOOGLE_CREDENTIALS"
|
||||
#
|
||||
# # AWS Bedrock example (requires bedrock_key_config)
|
||||
# bedrock:
|
||||
# keys:
|
||||
# - name: "bedrock-key"
|
||||
# value: ""
|
||||
# weight: 1
|
||||
# bedrock_key_config:
|
||||
# region: "us-east-1"
|
||||
# access_key: "env.AWS_ACCESS_KEY_ID"
|
||||
# secret_key: "env.AWS_SECRET_ACCESS_KEY"
|
||||
|
||||
# Provider secrets - use existing Kubernetes secrets for provider API keys
|
||||
# These will be injected as environment variables that can be referenced in providers config
|
||||
providerSecrets: {}
|
||||
# openai:
|
||||
# existingSecret: "my-openai-secret"
|
||||
# key: "api-key"
|
||||
# envVar: "OPENAI_API_KEY" # Environment variable name to inject
|
||||
# anthropic:
|
||||
# existingSecret: "my-anthropic-secret"
|
||||
# key: "api-key"
|
||||
# envVar: "ANTHROPIC_API_KEY"
|
||||
|
||||
# MCP (Model Context Protocol) configuration
|
||||
mcp:
|
||||
enabled: false
|
||||
clientConfigs: []
|
||||
# - name: "example-mcp"
|
||||
# connectionType: "stdio"
|
||||
# stdioConfig:
|
||||
# command: "/path/to/mcp/server"
|
||||
# args: []
|
||||
# envs: []
|
||||
# # Optional: source connection_string from a Kubernetes secret.
|
||||
# # When set, chart injects BIFROST_MCP_<NAME>_CONNECTION_STRING
|
||||
# # into the pod and rewrites connection_string in config.json
|
||||
# # to `env.BIFROST_MCP_<NAME>_CONNECTION_STRING`.
|
||||
# secretRef:
|
||||
# name: "" # k8s secret name
|
||||
# connectionStringKey: "connection-string" # key within the secret
|
||||
# toolSyncInterval: "10m" # Global tool sync interval (Go duration)
|
||||
# Tool manager configuration
|
||||
toolManagerConfig:
|
||||
toolExecutionTimeout: 30
|
||||
maxAgentDepth: 10
|
||||
# codeModeBindingLevel: "" # Code mode binding level (server or tool)
|
||||
|
||||
# Plugins configuration
|
||||
# Plugin version must be >= 1 (schema minimum). Use values > 1 to force DB-backed plugin config replacement on upgrade.
|
||||
plugins:
|
||||
telemetry:
|
||||
enabled: false
|
||||
version: 1
|
||||
config:
|
||||
custom_labels: []
|
||||
# push_gateway:
|
||||
# enabled: false
|
||||
# push_gateway_url: ""
|
||||
# job_name: "bifrost"
|
||||
# instance_id: ""
|
||||
# push_interval: 15
|
||||
# basic_auth:
|
||||
# username: ""
|
||||
# password: ""
|
||||
|
||||
logging:
|
||||
enabled: false
|
||||
version: 1
|
||||
config:
|
||||
disable_content_logging: false
|
||||
logging_headers: []
|
||||
|
||||
governance:
|
||||
enabled: false
|
||||
version: 1
|
||||
config:
|
||||
is_vk_mandatory: false
|
||||
required_headers: []
|
||||
is_enterprise: false
|
||||
|
||||
maxim:
|
||||
enabled: false
|
||||
version: 1
|
||||
config:
|
||||
api_key: ""
|
||||
log_repo_id: ""
|
||||
# Use existing Kubernetes secret for API key (takes precedence over config.api_key)
|
||||
secretRef:
|
||||
name: ""
|
||||
key: "api-key"
|
||||
|
||||
semanticCache:
|
||||
enabled: false
|
||||
version: 1
|
||||
config:
|
||||
# Semantic caching mode (dimension > 1): requires provider, keys, and embedding_model
|
||||
# Direct caching mode (dimension: 1): hash-based exact matching, no embedding provider needed
|
||||
provider: "openai"
|
||||
keys: []
|
||||
embedding_model: "text-embedding-3-small"
|
||||
dimension: 1536
|
||||
threshold: 0.8
|
||||
ttl: "5m"
|
||||
conversation_history_threshold: 3
|
||||
cache_by_model: true
|
||||
cache_by_provider: true
|
||||
exclude_system_prompt: false
|
||||
cleanup_on_shutdown: false
|
||||
vector_store_namespace: ""
|
||||
|
||||
otel:
|
||||
enabled: false
|
||||
version: 1
|
||||
config:
|
||||
service_name: "bifrost"
|
||||
collector_url: ""
|
||||
trace_type: "genai_extension"
|
||||
protocol: "grpc"
|
||||
# Push-based metrics export via OTLP (recommended for multi-node clusters)
|
||||
metrics_enabled: false
|
||||
metrics_endpoint: "" # e.g., http://otel-collector:4318/v1/metrics (HTTP) or otel-collector:4317 (gRPC)
|
||||
metrics_push_interval: 15 # Push interval in seconds (1-300)
|
||||
# Custom headers for the collector (supports env.VAR_NAME prefix for env var substitution)
|
||||
headers: {}
|
||||
# TLS configuration
|
||||
tls_ca_cert: "" # Path to TLS CA certificate file
|
||||
insecure: false # Skip TLS verification (ignored if tls_ca_cert is set)
|
||||
|
||||
datadog:
|
||||
enabled: false
|
||||
version: 1
|
||||
config:
|
||||
service_name: "bifrost"
|
||||
agent_addr: "localhost:8126"
|
||||
env: ""
|
||||
version: ""
|
||||
custom_tags: {}
|
||||
enable_traces: true
|
||||
|
||||
# Custom/dynamic plugins
|
||||
custom: []
|
||||
# - name: "my-custom-plugin"
|
||||
# enabled: true
|
||||
# path: "/plugins/my-plugin.so"
|
||||
# version: 1 # must be >= 1; increase to force DB-backed plugin config replacement
|
||||
# config:
|
||||
# key: value
|
||||
|
||||
# Governance configuration for budgets, rate limits, customers, teams, virtual keys, and routing rules
|
||||
governance:
|
||||
budgets: []
|
||||
# - id: "budget-1"
|
||||
# max_limit: 100
|
||||
# reset_duration: "1M" # Supports: 30s, 5m, 1h, 1d, 1w, 1M, 1Y
|
||||
rateLimits: []
|
||||
# - id: "rate-limit-1"
|
||||
# token_max_limit: 100000
|
||||
# token_reset_duration: "1d"
|
||||
# request_max_limit: 1000
|
||||
# request_reset_duration: "1h"
|
||||
customers: []
|
||||
# - id: "customer-1"
|
||||
# name: "Customer Name"
|
||||
# budget_id: "budget-1"
|
||||
# rate_limit_id: "rate-limit-1"
|
||||
teams: []
|
||||
# - id: "team-1"
|
||||
# name: "Team Name"
|
||||
# customer_id: "customer-1"
|
||||
# budget_id: "budget-1"
|
||||
# rate_limit_id: "rate-limit-1"
|
||||
# profile: {} # Team profile data
|
||||
# config: {} # Team configuration data
|
||||
# claims: {} # Team claims data
|
||||
virtualKeys: []
|
||||
# - id: "vk-1"
|
||||
# name: "Virtual Key 1"
|
||||
# description: "Virtual key description"
|
||||
# value: "vk-..." # Optional - auto-generated if omitted
|
||||
# is_active: true
|
||||
# team_id: "team-1" # Mutually exclusive with customer_id
|
||||
# customer_id: "" # Mutually exclusive with team_id
|
||||
# budget_id: "budget-1"
|
||||
# rate_limit_id: "rate-limit-1"
|
||||
# # Provider-specific configurations (empty means all providers allowed)
|
||||
# provider_configs:
|
||||
# - provider: "openai"
|
||||
# weight: 1.0
|
||||
# allowed_models: ["gpt-4o"]
|
||||
# budget_id: ""
|
||||
# rate_limit_id: ""
|
||||
# keys:
|
||||
# - key_id: "uuid-of-key"
|
||||
# name: "my-key"
|
||||
# value: "sk-..."
|
||||
# # MCP configurations for this virtual key
|
||||
# mcp_configs:
|
||||
# - mcp_client_id: 1
|
||||
# tools_to_execute: ["tool1", "tool2"]
|
||||
modelConfigs: []
|
||||
# - id: "model-config-1"
|
||||
# model_name: "gpt-4o"
|
||||
# provider: "openai"
|
||||
# budget_id: "budget-1"
|
||||
# rate_limit_id: "rate-limit-1"
|
||||
providers: []
|
||||
# - name: "openai"
|
||||
# budget_id: "budget-1"
|
||||
# rate_limit_id: "rate-limit-1"
|
||||
# send_back_raw_request: false
|
||||
# send_back_raw_response: false
|
||||
routingRules: []
|
||||
# - id: "route-1"
|
||||
# name: "Route to Azure"
|
||||
# description: "Route GPT requests to Azure"
|
||||
# enabled: true
|
||||
# cel_expression: "model.startsWith('gpt-')"
|
||||
# targets:
|
||||
# - provider: "azure"
|
||||
# model: "" # Empty means use original model
|
||||
# weight: 1.0
|
||||
# fallbacks: ["openai"]
|
||||
# scope: "global" # Options: global, team, customer, virtual_key
|
||||
# scope_id: "" # Required for non-global scopes
|
||||
# priority: 0 # Lower = evaluated first
|
||||
authConfig:
|
||||
adminUsername: ""
|
||||
adminPassword: ""
|
||||
isEnabled: false
|
||||
disableAuthOnInference: false
|
||||
# Use existing Kubernetes secret for admin credentials
|
||||
existingSecret: ""
|
||||
usernameKey: "username"
|
||||
passwordKey: "password"
|
||||
|
||||
# Cluster mode configuration for distributed deployments
|
||||
cluster:
|
||||
enabled: false
|
||||
# region: "" # Region identifier for cluster
|
||||
peers: []
|
||||
# - "bifrost-0.bifrost-headless:7946"
|
||||
# - "bifrost-1.bifrost-headless:7946"
|
||||
gossip:
|
||||
port: 7946
|
||||
config:
|
||||
timeoutSeconds: 10
|
||||
successThreshold: 3
|
||||
failureThreshold: 3
|
||||
discovery:
|
||||
enabled: false
|
||||
# Discovery type: kubernetes, dns, udp, consul, etcd, mdns
|
||||
type: ""
|
||||
# Service name used by consul/etcd/udp discovery and as mDNS default
|
||||
# This must be explicitly set for consul/etcd/udp discovery.
|
||||
serviceName: ""
|
||||
allowedAddressSpace: []
|
||||
# Kubernetes discovery
|
||||
k8sNamespace: ""
|
||||
k8sLabelSelector: ""
|
||||
# DNS discovery
|
||||
dnsNames: []
|
||||
# UDP broadcast discovery
|
||||
udpBroadcastPort: 0
|
||||
# Consul discovery
|
||||
consulAddress: ""
|
||||
# Etcd discovery
|
||||
etcdEndpoints: []
|
||||
# mDNS discovery
|
||||
mdnsService: ""
|
||||
|
||||
# SCIM/SSO configuration for enterprise SSO
|
||||
scim:
|
||||
enabled: false
|
||||
# Provider: okta, entra
|
||||
provider: ""
|
||||
config: {}
|
||||
# Okta configuration:
|
||||
# issuerUrl: "https://your-domain.okta.com/oauth2/default"
|
||||
# clientId: ""
|
||||
# clientSecret: ""
|
||||
# apiToken: ""
|
||||
# audience: ""
|
||||
# userIdField: "sub"
|
||||
# teamIdsField: "groups"
|
||||
# rolesField: "roles"
|
||||
#
|
||||
# Entra (Azure AD) configuration:
|
||||
# tenantId: ""
|
||||
# clientId: ""
|
||||
# clientSecret: ""
|
||||
# cloud: "commercial" # or "gcc-high" or "dod"
|
||||
# audience: ""
|
||||
# appIdUri: ""
|
||||
# userIdField: "oid"
|
||||
# teamIdsField: "groups"
|
||||
# rolesField: "roles"
|
||||
|
||||
# Load balancer configuration for intelligent request routing
|
||||
loadBalancer:
|
||||
enabled: false
|
||||
trackerConfig: {}
|
||||
bootstrap: {}
|
||||
|
||||
# Guardrails configuration for content moderation and policy enforcement
|
||||
guardrails:
|
||||
rules: []
|
||||
# - id: 1
|
||||
# name: "Block PII"
|
||||
# description: "Block requests containing PII"
|
||||
# enabled: true
|
||||
# cel_expression: "!contains(request.body, 'SSN')"
|
||||
# apply_to: "input"
|
||||
# sampling_rate: 100
|
||||
# timeout: 1000
|
||||
providers: []
|
||||
# - id: 1
|
||||
# provider_name: "bedrock"
|
||||
# policy_name: "content-filter"
|
||||
# enabled: true
|
||||
# config: {}
|
||||
|
||||
# Access profiles (enterprise): seed RBAC access profile templates from Helm.
|
||||
# This is rendered directly as top-level `access_profiles` in config.json.
|
||||
accessProfiles: []
|
||||
# - name: "platform-default"
|
||||
# description: "Default platform profile"
|
||||
# is_active: true
|
||||
# tags: ["platform", "default"]
|
||||
# budgets:
|
||||
# - id: "ap-budget-1"
|
||||
# max_limit: 100
|
||||
# reset_duration: "1M"
|
||||
# rate_limit:
|
||||
# id: "ap-rate-limit-1"
|
||||
# token_max_limit: 200000
|
||||
# token_reset_duration: "1h"
|
||||
# provider_configs:
|
||||
# - provider_name: "openai"
|
||||
# all_models_allowed: false
|
||||
# allowed_models: ["gpt-4o", "gpt-4o-mini"]
|
||||
# mcp_tool_groups:
|
||||
# - tool_group_id: 1
|
||||
# mcp_servers:
|
||||
# - mcp_server_id: "github"
|
||||
# mcp_tool_overrides:
|
||||
# - mcp_client_id: "github"
|
||||
# tool_name: "create_pull_request"
|
||||
# action: "include"
|
||||
|
||||
# Audit logs configuration for CADF-compliant activity logging
|
||||
auditLogs:
|
||||
disabled: false
|
||||
hmacKey: ""
|
||||
|
||||
# Large payload optimization - streams large payloads without full materialization
|
||||
# largePayloadOptimization:
|
||||
# enabled: false
|
||||
# requestThresholdBytes: 10485760 # 10MB
|
||||
# responseThresholdBytes: 10485760 # 10MB
|
||||
# prefetchSizeBytes: 65536 # 64KB
|
||||
# maxPayloadBytes: 524288000 # 500MB
|
||||
# truncatedLogBytes: 1048576 # 1MB
|
||||
|
||||
# WebSocket gateway configuration (Responses API, Realtime API)
|
||||
# websocket:
|
||||
# maxConnectionsPerUser: 100
|
||||
# transcriptBufferSize: 100
|
||||
# pool:
|
||||
# maxIdlePerKey: 50
|
||||
# maxTotalConnections: 1000
|
||||
# idleTimeoutSeconds: 600
|
||||
# maxConnectionLifetimeSeconds: 7200
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
# Default storage mode: sqlite or postgres
|
||||
# Used as fallback when per-store type is not specified
|
||||
mode: sqlite # Options: sqlite, postgres
|
||||
|
||||
# Persistent volume for SQLite databases (when using sqlite for any store)
|
||||
persistence:
|
||||
enabled: true
|
||||
# storageClass: "-" # Use default storage class
|
||||
accessMode: ReadWriteOnce
|
||||
size: 10Gi
|
||||
# existingClaim: "" # Use an existing PVC
|
||||
|
||||
# Configuration store settings
|
||||
configStore:
|
||||
enabled: true
|
||||
# Backend type for config store. Empty string uses storage.mode as default
|
||||
type: "" # Options: sqlite, postgres, or "" (uses storage.mode)
|
||||
# PostgreSQL connection pool tuning (only applies when type is postgres)
|
||||
# maxIdleConns: 5
|
||||
# maxOpenConns: 50
|
||||
|
||||
# Logs store settings
|
||||
logsStore:
|
||||
enabled: true
|
||||
# Backend type for logs store. Empty string uses storage.mode as default
|
||||
type: "" # Options: sqlite, postgres, or "" (uses storage.mode)
|
||||
# PostgreSQL connection pool tuning (only applies when type is postgres)
|
||||
# maxIdleConns: 5
|
||||
# maxOpenConns: 50
|
||||
|
||||
# Object storage for offloading large log payloads (optional)
|
||||
# When enabled, request/response payloads are stored in S3/GCS
|
||||
# while the DB keeps only lightweight index data for fast analytics.
|
||||
objectStorage:
|
||||
enabled: false
|
||||
# type: s3 # Options: s3, gcs
|
||||
# bucket: "" # Bucket name
|
||||
# prefix: bifrost # Key prefix for stored objects
|
||||
# compress: false # Enable gzip compression for stored objects
|
||||
|
||||
# S3 configuration (when type is s3)
|
||||
# region: us-east-1
|
||||
# endpoint: "" # Custom endpoint for MinIO/R2
|
||||
# accessKeyId: "" # Leave empty to use default AWS credential chain
|
||||
# secretAccessKey: "" # (instance role, env vars, shared credentials, etc.)
|
||||
# sessionToken: "" # AWS STS session token (optional)
|
||||
# roleArn: "" # AWS IAM role ARN to assume via STS (works with static creds or instance role)
|
||||
# forcePathStyle: false # Set true for MinIO
|
||||
|
||||
# GCS configuration (when type is gcs)
|
||||
# projectId: ""
|
||||
# credentialsJson: "" # Service account JSON, omit for default credentials
|
||||
|
||||
# PostgreSQL configuration (when any store uses postgres)
|
||||
postgresql:
|
||||
# Deploy PostgreSQL as part of this chart
|
||||
enabled: false
|
||||
|
||||
# Use external PostgreSQL instance
|
||||
external:
|
||||
enabled: false
|
||||
host: ""
|
||||
port: 5432
|
||||
user: bifrost
|
||||
password: ""
|
||||
database: bifrost
|
||||
sslMode: disable
|
||||
# Use existing Kubernetes secret for password (takes precedence over password field)
|
||||
existingSecret: ""
|
||||
passwordKey: "password"
|
||||
|
||||
# PostgreSQL image configuration
|
||||
image:
|
||||
repository: postgres
|
||||
tag: "16-alpine"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# PostgreSQL subchart configuration (when postgresql.enabled is true)
|
||||
auth:
|
||||
username: bifrost
|
||||
password: bifrost_password
|
||||
database: bifrost
|
||||
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 8Gi
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
metrics:
|
||||
enabled: false
|
||||
|
||||
# Vector store configuration
|
||||
vectorStore:
|
||||
# Enable vector store for semantic caching
|
||||
enabled: false
|
||||
type: none # Options: none, weaviate, redis, qdrant
|
||||
|
||||
# Weaviate configuration
|
||||
weaviate:
|
||||
# Deploy Weaviate as part of this chart
|
||||
enabled: false
|
||||
|
||||
# Use external Weaviate instance
|
||||
external:
|
||||
enabled: false
|
||||
scheme: http
|
||||
host: ""
|
||||
apiKey: ""
|
||||
grpcHost: ""
|
||||
grpcSecured: false
|
||||
# timeout: "5s" # Timeout for operations (e.g., "5s", "30s")
|
||||
# className: "" # Class name for vector store
|
||||
# Use existing Kubernetes secret for API key (takes precedence over apiKey field)
|
||||
existingSecret: ""
|
||||
apiKeyKey: "api-key"
|
||||
|
||||
# Weaviate subchart configuration (when weaviate.enabled is true)
|
||||
replicas: 1
|
||||
|
||||
image:
|
||||
repository: semitechnologies/weaviate
|
||||
tag: "1.24.1"
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
env:
|
||||
QUERY_DEFAULTS_LIMIT: "25"
|
||||
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true"
|
||||
PERSISTENCE_DATA_PATH: "/var/lib/weaviate"
|
||||
DEFAULT_VECTORIZER_MODULE: "none"
|
||||
ENABLE_MODULES: ""
|
||||
CLUSTER_HOSTNAME: "node1"
|
||||
|
||||
# Redis configuration
|
||||
redis:
|
||||
# Deploy Redis as part of this chart
|
||||
enabled: false
|
||||
|
||||
# Use external Redis instance
|
||||
external:
|
||||
enabled: false
|
||||
host: ""
|
||||
port: 6379
|
||||
username: ""
|
||||
password: ""
|
||||
database: 0
|
||||
useTls: false # Enable TLS for Redis connection
|
||||
insecureSkipVerify: false # Skip TLS certificate verification
|
||||
caCertPem: "" # PEM-encoded CA certificate to trust for Redis TLS
|
||||
clusterMode: false # Use Redis Cluster mode (required for AWS MemoryDB)
|
||||
# Connection pool tuning (optional)
|
||||
# poolSize: 10 # Maximum number of socket connections
|
||||
# maxActiveConns: 0 # Maximum number of active connections
|
||||
# minIdleConns: 0 # Minimum number of idle connections
|
||||
# maxIdleConns: 0 # Maximum number of idle connections
|
||||
# connMaxLifetime: "" # Connection max lifetime (e.g., "30m")
|
||||
# connMaxIdleTime: "" # Connection max idle time (e.g., "5m")
|
||||
# dialTimeout: "" # Socket connection timeout (e.g., "5s")
|
||||
# readTimeout: "" # Socket read timeout (e.g., "3s")
|
||||
# writeTimeout: "" # Socket write timeout (e.g., "3s")
|
||||
# contextTimeout: "" # Redis operation timeout (e.g., "10s")
|
||||
# Use existing Kubernetes secret for password (takes precedence over password field)
|
||||
existingSecret: ""
|
||||
passwordKey: "password"
|
||||
|
||||
# Redis image configuration
|
||||
image:
|
||||
repository: redis
|
||||
tag: "7-alpine"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Redis subchart configuration (when redis.enabled is true)
|
||||
auth:
|
||||
enabled: true
|
||||
password: "redis_password"
|
||||
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 8Gi
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
metrics:
|
||||
enabled: false
|
||||
|
||||
# Qdrant configuration
|
||||
qdrant:
|
||||
# Deploy Qdrant as part of this chart
|
||||
enabled: false
|
||||
|
||||
# Use external Qdrant instance
|
||||
external:
|
||||
enabled: false
|
||||
host: ""
|
||||
port: 6334
|
||||
apiKey: ""
|
||||
useTls: false
|
||||
# Use existing Kubernetes secret for API key (takes precedence over apiKey field)
|
||||
existingSecret: ""
|
||||
apiKeyKey: "api-key"
|
||||
|
||||
# Qdrant image configuration
|
||||
image:
|
||||
repository: qdrant/qdrant
|
||||
tag: "v1.16.0"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Qdrant subchart configuration (when qdrant.enabled is true)
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
# Pinecone configuration (external only, no self-hosted option)
|
||||
pinecone:
|
||||
external:
|
||||
enabled: false
|
||||
apiKey: ""
|
||||
indexHost: "" # Index host URL from Pinecone console (e.g., your-index.svc.environment.pinecone.io)
|
||||
# Use existing Kubernetes secret for API key (takes precedence over apiKey field)
|
||||
existingSecret: ""
|
||||
apiKeyKey: "api-key"
|
||||
|
||||
# Environment variables
|
||||
env: []
|
||||
# - name: CUSTOM_ENV_VAR
|
||||
# value: "value"
|
||||
|
||||
# Additional environment variables appended after env
|
||||
extraEnv: {}
|
||||
# ANOTHER_ENV_VAR: "value"
|
||||
|
||||
# Environment variables from secrets/configmaps
|
||||
envFrom: []
|
||||
# - secretRef:
|
||||
# name: my-secret
|
||||
# - configMapRef:
|
||||
# name: my-configmap
|
||||
|
||||
# Init containers to run before the main application container.
|
||||
# Provide a list of init containers using standard Kubernetes container spec.
|
||||
initContainers: []
|
||||
673
helm-charts/index.yaml
Normal file
673
helm-charts/index.yaml
Normal file
@@ -0,0 +1,673 @@
|
||||
apiVersion: v1
|
||||
entries:
|
||||
bifrost:
|
||||
- apiVersion: v2
|
||||
appVersion: 1.5.0-prerelease4
|
||||
created: "2026-04-21T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getbifrost.ai/favicon.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: support@getbifrost.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.1.2.tgz
|
||||
version: 2.1.2
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-04-15T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.1.0-prerelease1.tgz
|
||||
version: 2.1.0-prerelease1
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-04-13T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.18-rc.1.tgz
|
||||
version: 2.0.18-rc.1
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-04-08T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.17.tgz
|
||||
version: 2.0.17
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-04-08T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.16.tgz
|
||||
version: 2.0.16
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-04-07T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.15.tgz
|
||||
version: 2.0.15
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-03-20T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.14.tgz
|
||||
version: 2.0.14
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-03-11T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.13.tgz
|
||||
version: 2.0.13
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-03-06T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.12.tgz
|
||||
version: 2.0.12
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.11
|
||||
created: "2026-03-05T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.11.tgz
|
||||
version: 2.0.11
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.8
|
||||
created: "2026-03-03T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.10.tgz
|
||||
version: 2.0.10
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.8
|
||||
created: "2026-02-26T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.9.tgz
|
||||
version: 2.0.9
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-02-19T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.8.tgz
|
||||
version: 2.0.8
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-02-17T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.7.tgz
|
||||
version: 2.0.7
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-02-17T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.6.tgz
|
||||
version: 2.0.6
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-02-13T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.5.tgz
|
||||
version: 2.0.5
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-02-10T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.4.tgz
|
||||
version: 2.0.4
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-02-05T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.3.tgz
|
||||
version: 2.0.3
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-01-31T21:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.2.tgz
|
||||
version: 2.0.2
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-01-31T20:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.1.tgz
|
||||
version: 2.0.1
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2026-01-31T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-2.0.0.tgz
|
||||
version: 2.0.0
|
||||
- apiVersion: v2
|
||||
appVersion: 1.5.2
|
||||
created: "2026-01-28T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.7.0.tgz
|
||||
version: 1.7.0
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.2
|
||||
created: "2026-01-23T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.6.0.tgz
|
||||
version: 1.6.0
|
||||
- apiVersion: v2
|
||||
appVersion: 1.5.3
|
||||
created: "2026-01-16T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.5.3.tgz
|
||||
version: 1.5.3
|
||||
- apiVersion: v2
|
||||
appVersion: 1.5.2
|
||||
created: "2026-01-05T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.5.2.tgz
|
||||
version: 1.5.2
|
||||
- apiVersion: v2
|
||||
appVersion: 1.5.1
|
||||
created: "2025-12-12T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.5.1.tgz
|
||||
version: 1.5.1
|
||||
- apiVersion: v2
|
||||
appVersion: 1.5.0
|
||||
created: "2025-12-11T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.5.0.tgz
|
||||
version: 1.5.0
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.3
|
||||
created: "2025-12-10T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.4.3.tgz
|
||||
version: 1.4.3
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.2
|
||||
created: "2025-12-08T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.4.2.tgz
|
||||
version: 1.4.2
|
||||
- apiVersion: v2
|
||||
appVersion: 1.4.1
|
||||
created: "2025-11-28T12:00:00.000000+00:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: ""
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.4.1.tgz
|
||||
version: 1.4.1
|
||||
- apiVersion: v2
|
||||
appVersion: 1.3.36
|
||||
created: "2025-11-26T09:56:49.837282+03:00"
|
||||
description: A Helm chart for deploying Bifrost - AI Gateway with unified interface
|
||||
for multiple providers
|
||||
digest: 6e5b4339411070149533006533529840664282c0e40897b589189841c6580331
|
||||
home: https://www.getmaxim.ai/bifrost
|
||||
icon: https://www.getmaxim.ai/bifrost/bifrost-logo-only.png
|
||||
keywords:
|
||||
- ai
|
||||
- gateway
|
||||
- llm
|
||||
- openai
|
||||
- anthropic
|
||||
maintainers:
|
||||
- email: akshay@getmaxim.ai
|
||||
name: Bifrost Team
|
||||
name: bifrost
|
||||
sources:
|
||||
- https://github.com/maximhq/bifrost
|
||||
type: application
|
||||
urls:
|
||||
- https://maximhq.github.io/bifrost/helm-charts/bifrost-1.3.36.tgz
|
||||
version: 1.3.36
|
||||
generated: "2026-04-13T12:00:00.000000+00:00"
|
||||
Reference in New Issue
Block a user