| #!/usr/bin/env bash |
| set -euo pipefail |
|
|
| |
| |
|
|
| |
| if command -v readlink >/dev/null 2>&1 && readlink -f "$0" >/dev/null 2>&1; then |
| SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" |
| else |
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" |
| fi |
| REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" |
|
|
| CONFIG_SCHEMA="$REPO_ROOT/transports/config.schema.json" |
| HELM_SCHEMA="$REPO_ROOT/helm-charts/bifrost/values.schema.json" |
|
|
| echo "π Comparing schemas:" |
| echo " Config schema: $CONFIG_SCHEMA" |
| echo " Helm schema: $HELM_SCHEMA" |
|
|
| |
| if [ ! -f "$CONFIG_SCHEMA" ]; then |
| echo "β Config schema not found: $CONFIG_SCHEMA" |
| exit 1 |
| fi |
|
|
| if [ ! -f "$HELM_SCHEMA" ]; then |
| echo "β Helm schema not found: $HELM_SCHEMA" |
| exit 1 |
| fi |
|
|
| |
| if ! command -v jq &> /dev/null; then |
| echo "β οΈ jq not found, skipping detailed schema comparison" |
| echo " Install jq for full schema validation" |
| exit 0 |
| fi |
|
|
| ERRORS=0 |
|
|
| |
| extract_required_fields() { |
| local schema_file="$1" |
| local def_path="$2" |
| jq -r "$def_path.required // [] | .[]" "$schema_file" 2>/dev/null | sort |
| } |
|
|
| |
| def_exists() { |
| local schema_file="$1" |
| local def_path="$2" |
| jq -e "$def_path" "$schema_file" > /dev/null 2>&1 |
| } |
|
|
| echo "" |
| echo "π Checking required fields in governance entities..." |
|
|
| |
| CONFIG_BUDGET_REQUIRED=$(jq -r '.properties.governance.properties.budgets.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_BUDGET_REQUIRED=$(jq -r '.properties.bifrost.properties.governance.properties.budgets.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_BUDGET_REQUIRED" != "$HELM_BUDGET_REQUIRED" ]; then |
| echo "β Budget required fields mismatch:" |
| echo " Config: [$CONFIG_BUDGET_REQUIRED]" |
| echo " Helm: [$HELM_BUDGET_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Budget required fields match: [$CONFIG_BUDGET_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_RATELIMIT_REQUIRED=$(jq -r '.properties.governance.properties.rate_limits.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_RATELIMIT_REQUIRED=$(jq -r '.properties.bifrost.properties.governance.properties.rateLimits.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_RATELIMIT_REQUIRED" != "$HELM_RATELIMIT_REQUIRED" ]; then |
| echo "β Rate limits required fields mismatch:" |
| echo " Config: [$CONFIG_RATELIMIT_REQUIRED]" |
| echo " Helm: [$HELM_RATELIMIT_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Rate limits required fields match: [$CONFIG_RATELIMIT_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_CUSTOMER_REQUIRED=$(jq -r '.properties.governance.properties.customers.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_CUSTOMER_REQUIRED=$(jq -r '.properties.bifrost.properties.governance.properties.customers.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_CUSTOMER_REQUIRED" != "$HELM_CUSTOMER_REQUIRED" ]; then |
| echo "β Customer required fields mismatch:" |
| echo " Config: [$CONFIG_CUSTOMER_REQUIRED]" |
| echo " Helm: [$HELM_CUSTOMER_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Customer required fields match: [$CONFIG_CUSTOMER_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_TEAM_REQUIRED=$(jq -r '.properties.governance.properties.teams.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_TEAM_REQUIRED=$(jq -r '.properties.bifrost.properties.governance.properties.teams.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_TEAM_REQUIRED" != "$HELM_TEAM_REQUIRED" ]; then |
| echo "β Team required fields mismatch:" |
| echo " Config: [$CONFIG_TEAM_REQUIRED]" |
| echo " Helm: [$HELM_TEAM_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Team required fields match: [$CONFIG_TEAM_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_VK_REQUIRED=$(jq -r '.properties.governance.properties.virtual_keys.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VK_REQUIRED=$(jq -r '.properties.bifrost.properties.governance.properties.virtualKeys.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VK_REQUIRED" != "$HELM_VK_REQUIRED" ]; then |
| echo "β Virtual key required fields mismatch:" |
| echo " Config: [$CONFIG_VK_REQUIRED]" |
| echo " Helm: [$HELM_VK_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Virtual key required fields match: [$CONFIG_VK_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo 'π Checking required fields in $defs...' |
|
|
| |
| CONFIG_BASEKEY_REQUIRED=$(jq -r '."$defs".base_key.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_BASEKEY_REQUIRED=$(jq -r '."$defs".providerKey.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_BASEKEY_REQUIRED" != "$HELM_BASEKEY_REQUIRED" ]; then |
| echo "β Provider key (base_key) required fields mismatch:" |
| echo " Config: [$CONFIG_BASEKEY_REQUIRED]" |
| echo " Helm: [$HELM_BASEKEY_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Provider key required fields match: [$CONFIG_BASEKEY_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_AZURE_REQUIRED=$(jq -r '."$defs".azure_key.allOf[1].properties.azure_key_config.properties | keys | map(select(. as $k | ["endpoint", "api_version"] | index($k))) | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "endpoint,api_version") |
| HELM_AZURE_REQUIRED=$(jq -r '."$defs".providerKey.properties.azure_key_config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| |
| CONFIG_AZURE_REQ_NORM=$(jq -r '."$defs".azure_key.allOf[1].properties.azure_key_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| if [ -z "$CONFIG_AZURE_REQ_NORM" ]; then |
| |
| CONFIG_AZURE_REQ_NORM=$(jq -r '."$defs".azure_key_config.required // ["endpoint", "api_version"] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "api_version,endpoint") |
| fi |
|
|
| if [ "$CONFIG_AZURE_REQ_NORM" != "$HELM_AZURE_REQUIRED" ]; then |
| echo "β Azure key config required fields mismatch:" |
| echo " Config: [$CONFIG_AZURE_REQ_NORM]" |
| echo " Helm: [$HELM_AZURE_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Azure key config required fields match: [$HELM_AZURE_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_VERTEX_REQUIRED=$(jq -r '."$defs".vertex_key.allOf[1].properties.vertex_key_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VERTEX_REQUIRED=$(jq -r '."$defs".providerKey.properties.vertex_key_config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VERTEX_REQUIRED" != "$HELM_VERTEX_REQUIRED" ]; then |
| echo "β Vertex key config required fields mismatch:" |
| echo " Config: [$CONFIG_VERTEX_REQUIRED]" |
| echo " Helm: [$HELM_VERTEX_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Vertex key config required fields match: [$CONFIG_VERTEX_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_BEDROCK_REQUIRED=$(jq -r '."$defs".bedrock_key.allOf[1].properties.bedrock_key_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_BEDROCK_REQUIRED=$(jq -r '."$defs".providerKey.properties.bedrock_key_config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_BEDROCK_REQUIRED" != "$HELM_BEDROCK_REQUIRED" ]; then |
| echo "β Bedrock key config required fields mismatch:" |
| echo " Config: [$CONFIG_BEDROCK_REQUIRED]" |
| echo " Helm: [$HELM_BEDROCK_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Bedrock key config required fields match: [$CONFIG_BEDROCK_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_VLLM_REQUIRED=$(jq -r '."$defs".vllm_key.allOf[1].properties.vllm_key_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VLLM_REQUIRED=$(jq -r '."$defs".providerKey.properties.vllm_key_config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VLLM_REQUIRED" != "$HELM_VLLM_REQUIRED" ]; then |
| echo "β VLLM key config required fields mismatch:" |
| echo " Config: [$CONFIG_VLLM_REQUIRED]" |
| echo " Helm: [$HELM_VLLM_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
VLLM key config required fields match: [$HELM_VLLM_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_CONCURRENCY_REQUIRED=$(jq -r '."$defs".concurrency_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_CONCURRENCY_REQUIRED=$(jq -r '."$defs".concurrencyConfig.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_CONCURRENCY_REQUIRED" != "$HELM_CONCURRENCY_REQUIRED" ]; then |
| echo "β Concurrency config required fields mismatch:" |
| echo " Config: [$CONFIG_CONCURRENCY_REQUIRED]" |
| echo " Helm: [$HELM_CONCURRENCY_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Concurrency config required fields match: [$CONFIG_CONCURRENCY_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_PROXY_REQUIRED=$(jq -r '."$defs".proxy_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_PROXY_REQUIRED=$(jq -r '."$defs".proxyConfig.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_PROXY_REQUIRED" != "$HELM_PROXY_REQUIRED" ]; then |
| echo "β Proxy config required fields mismatch:" |
| echo " Config: [$CONFIG_PROXY_REQUIRED]" |
| echo " Helm: [$HELM_PROXY_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Proxy config required fields match: [$CONFIG_PROXY_REQUIRED]" |
| fi |
|
|
| |
| |
| CONFIG_MCP_REQUIRED=$(jq -r '."$defs".mcp_client_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_MCP_REQUIRED=$(jq -r '."$defs".mcpClientConfig.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| |
| CONFIG_MCP_NORM=$(echo "$CONFIG_MCP_REQUIRED" | tr ',' '\n' | sed 's/connection_type/connectionType/' | sort | tr '\n' ',' | sed 's/,$//') |
|
|
| if [ "$CONFIG_MCP_NORM" != "$HELM_MCP_REQUIRED" ]; then |
| echo "β MCP client config required fields mismatch:" |
| echo " Config: [$CONFIG_MCP_REQUIRED] (normalized: [$CONFIG_MCP_NORM])" |
| echo " Helm: [$HELM_MCP_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
MCP client config required fields match: [$HELM_MCP_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_PROVIDER_REQUIRED=$(jq -r '."$defs".provider.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_PROVIDER_REQUIRED=$(jq -r '."$defs".provider.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_PROVIDER_REQUIRED" != "$HELM_PROVIDER_REQUIRED" ]; then |
| echo "β Provider def required fields mismatch:" |
| echo " Config: [$CONFIG_PROVIDER_REQUIRED]" |
| echo " Helm: [$HELM_PROVIDER_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Provider def required fields match: [$CONFIG_PROVIDER_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_ROUTING_REQUIRED=$(jq -r '."$defs".routing_rule.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_ROUTING_REQUIRED=$(jq -r '.properties.bifrost.properties.governance.properties.routingRules.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_ROUTING_REQUIRED" != "$HELM_ROUTING_REQUIRED" ]; then |
| echo "β Routing rule required fields mismatch:" |
| echo " Config: [$CONFIG_ROUTING_REQUIRED]" |
| echo " Helm: [$HELM_ROUTING_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Routing rule required fields match: [$CONFIG_ROUTING_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking required fields in guardrails..." |
|
|
| |
| CONFIG_GUARDRAIL_RULE_REQUIRED=$(jq -r '.properties.guardrails_config.properties.guardrail_rules.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| |
| if [ -z "$CONFIG_GUARDRAIL_RULE_REQUIRED" ]; then |
| CONFIG_GUARDRAIL_RULE_REQUIRED=$(jq -r '."$defs".guardrails_config.properties.guardrail_rules.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| fi |
| HELM_GUARDRAIL_RULE_REQUIRED=$(jq -r '.properties.bifrost.properties.guardrails.properties.rules.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_GUARDRAIL_RULE_REQUIRED" != "$HELM_GUARDRAIL_RULE_REQUIRED" ]; then |
| echo "β Guardrail rules required fields mismatch:" |
| echo " Config: [$CONFIG_GUARDRAIL_RULE_REQUIRED]" |
| echo " Helm: [$HELM_GUARDRAIL_RULE_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Guardrail rules required fields match: [$CONFIG_GUARDRAIL_RULE_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_GUARDRAIL_PROV_REQUIRED=$(jq -r '.properties.guardrails_config.properties.guardrail_providers.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| if [ -z "$CONFIG_GUARDRAIL_PROV_REQUIRED" ]; then |
| CONFIG_GUARDRAIL_PROV_REQUIRED=$(jq -r '."$defs".guardrails_config.properties.guardrail_providers.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| fi |
| HELM_GUARDRAIL_PROV_REQUIRED=$(jq -r '.properties.bifrost.properties.guardrails.properties.providers.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_GUARDRAIL_PROV_REQUIRED" != "$HELM_GUARDRAIL_PROV_REQUIRED" ]; then |
| echo "β Guardrail providers required fields mismatch:" |
| echo " Config: [$CONFIG_GUARDRAIL_PROV_REQUIRED]" |
| echo " Helm: [$HELM_GUARDRAIL_PROV_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Guardrail providers required fields match: [$CONFIG_GUARDRAIL_PROV_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking required fields in cluster config..." |
|
|
| |
| CONFIG_GOSSIP_TOP_REQUIRED=$(jq -r '."$defs".cluster_config.properties.gossip.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_GOSSIP_TOP_REQUIRED=$(jq -r '.properties.bifrost.properties.cluster.properties.gossip.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_GOSSIP_TOP_REQUIRED" != "$HELM_GOSSIP_TOP_REQUIRED" ]; then |
| echo "β Cluster gossip required fields mismatch:" |
| echo " Config: [$CONFIG_GOSSIP_TOP_REQUIRED]" |
| echo " Helm: [$HELM_GOSSIP_TOP_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Cluster gossip required fields match: [$CONFIG_GOSSIP_TOP_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_GOSSIP_REQUIRED=$(jq -r '."$defs".cluster_config.properties.gossip.properties.config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_GOSSIP_REQUIRED=$(jq -r '.properties.bifrost.properties.cluster.properties.gossip.properties.config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| |
| CONFIG_GOSSIP_NORM=$(echo "$CONFIG_GOSSIP_REQUIRED" | tr ',' '\n' | sed 's/failure_threshold/failureThreshold/;s/success_threshold/successThreshold/;s/timeout_seconds/timeoutSeconds/' | sort | tr '\n' ',' | sed 's/,$//') |
|
|
| if [ "$CONFIG_GOSSIP_NORM" != "$HELM_GOSSIP_REQUIRED" ]; then |
| echo "β Cluster gossip config required fields mismatch:" |
| echo " Config: [$CONFIG_GOSSIP_REQUIRED] (normalized: [$CONFIG_GOSSIP_NORM])" |
| echo " Helm: [$HELM_GOSSIP_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Cluster gossip config required fields match: [$HELM_GOSSIP_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking required fields in virtual_key_provider_config..." |
|
|
| |
| CONFIG_VKPC_REQUIRED=$(jq -r '."$defs".virtual_key_provider_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VKPC_REQUIRED=$(jq -r '."$defs".virtualKeyProviderConfig.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VKPC_REQUIRED" != "$HELM_VKPC_REQUIRED" ]; then |
| echo "β Virtual key provider config required fields mismatch:" |
| echo " Config: [$CONFIG_VKPC_REQUIRED]" |
| echo " Helm: [$HELM_VKPC_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Virtual key provider config required fields match: [$CONFIG_VKPC_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_VKPC_KEY_REQUIRED=$(jq -r '."$defs".virtual_key_provider_config.properties.keys.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VKPC_KEY_REQUIRED=$(jq -r '."$defs".virtualKeyProviderConfig.properties.keys.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VKPC_KEY_REQUIRED" != "$HELM_VKPC_KEY_REQUIRED" ]; then |
| echo "β VK provider config key items required fields mismatch:" |
| echo " Config: [$CONFIG_VKPC_KEY_REQUIRED]" |
| echo " Helm: [$HELM_VKPC_KEY_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
VK provider config key items required fields match: [$CONFIG_VKPC_KEY_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_VKPC_AZURE_REQUIRED=$(jq -r '."$defs".virtual_key_provider_config.properties.keys.items.properties.azure_key_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VKPC_AZURE_REQUIRED=$(jq -r '."$defs".virtualKeyProviderConfig.properties.keys.items.properties.azure_key_config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VKPC_AZURE_REQUIRED" != "$HELM_VKPC_AZURE_REQUIRED" ]; then |
| echo "β VK provider config key azure_key_config required fields mismatch:" |
| echo " Config: [$CONFIG_VKPC_AZURE_REQUIRED]" |
| echo " Helm: [$HELM_VKPC_AZURE_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
VK provider config key azure_key_config required fields match: [$CONFIG_VKPC_AZURE_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_VKPC_VERTEX_REQUIRED=$(jq -r '."$defs".virtual_key_provider_config.properties.keys.items.properties.vertex_key_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VKPC_VERTEX_REQUIRED=$(jq -r '."$defs".virtualKeyProviderConfig.properties.keys.items.properties.vertex_key_config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VKPC_VERTEX_REQUIRED" != "$HELM_VKPC_VERTEX_REQUIRED" ]; then |
| echo "β VK provider config key vertex_key_config required fields mismatch:" |
| echo " Config: [$CONFIG_VKPC_VERTEX_REQUIRED]" |
| echo " Helm: [$HELM_VKPC_VERTEX_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
VK provider config key vertex_key_config required fields match: [$CONFIG_VKPC_VERTEX_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_VKPC_VLLM_REQUIRED=$(jq -r '."$defs".virtual_key_provider_config.properties.keys.items.properties.vllm_key_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VKPC_VLLM_REQUIRED=$(jq -r '."$defs".virtualKeyProviderConfig.properties.keys.items.properties.vllm_key_config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VKPC_VLLM_REQUIRED" != "$HELM_VKPC_VLLM_REQUIRED" ]; then |
| echo "β VK provider config key vllm_key_config required fields mismatch:" |
| echo " Config: [$CONFIG_VKPC_VLLM_REQUIRED]" |
| echo " Helm: [$HELM_VKPC_VLLM_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
VK provider config key vllm_key_config required fields match: [$CONFIG_VKPC_VLLM_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking required fields in virtual key MCP config..." |
|
|
| |
| CONFIG_VK_MCP_REQUIRED=$(jq -r '."$defs".virtual_key_mcp_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_VK_MCP_REQUIRED=$(jq -r '.properties.bifrost.properties.governance.properties.virtualKeys.items.properties.mcp_configs.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_VK_MCP_REQUIRED" != "$HELM_VK_MCP_REQUIRED" ]; then |
| echo "β Virtual key MCP config required fields mismatch:" |
| echo " Config: [$CONFIG_VK_MCP_REQUIRED]" |
| echo " Helm: [$HELM_VK_MCP_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Virtual key MCP config required fields match: [$CONFIG_VK_MCP_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking required fields in MCP sub-configs..." |
|
|
| |
| CONFIG_MCP_STDIO_REQUIRED=$(jq -r '."$defs".mcp_client_config.properties.stdio_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_MCP_STDIO_REQUIRED=$(jq -r '."$defs".mcpClientConfig.properties.stdioConfig.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_MCP_STDIO_REQUIRED" != "$HELM_MCP_STDIO_REQUIRED" ]; then |
| echo "β MCP stdio config required fields mismatch:" |
| echo " Config: [$CONFIG_MCP_STDIO_REQUIRED]" |
| echo " Helm: [$HELM_MCP_STDIO_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
MCP stdio config required fields match: [$CONFIG_MCP_STDIO_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_MCP_WS_REQUIRED=$(jq -r '."$defs".mcp_client_config.properties.websocket_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_MCP_WS_REQUIRED=$(jq -r '."$defs".mcpClientConfig.properties.websocketConfig.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_MCP_WS_REQUIRED" != "$HELM_MCP_WS_REQUIRED" ]; then |
| echo "β MCP websocket config required fields mismatch:" |
| echo " Config: [$CONFIG_MCP_WS_REQUIRED]" |
| echo " Helm: [$HELM_MCP_WS_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
MCP websocket config required fields match: [$CONFIG_MCP_WS_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_MCP_HTTP_REQUIRED=$(jq -r '."$defs".mcp_client_config.properties.http_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_MCP_HTTP_REQUIRED=$(jq -r '."$defs".mcpClientConfig.properties.httpConfig.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_MCP_HTTP_REQUIRED" != "$HELM_MCP_HTTP_REQUIRED" ]; then |
| echo "β MCP http config required fields mismatch:" |
| echo " Config: [$CONFIG_MCP_HTTP_REQUIRED]" |
| echo " Helm: [$HELM_MCP_HTTP_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
MCP http config required fields match: [$CONFIG_MCP_HTTP_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking required fields in SAML/SCIM config..." |
|
|
| |
| CONFIG_OKTA_REQUIRED=$(jq -r '."$defs".okta_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_OKTA_REQUIRED=$(jq -r '.properties.bifrost.properties.saml.allOf[0].then.properties.config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_OKTA_REQUIRED" != "$HELM_OKTA_REQUIRED" ]; then |
| echo "β Okta config required fields mismatch:" |
| echo " Config: [$CONFIG_OKTA_REQUIRED]" |
| echo " Helm: [$HELM_OKTA_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Okta config required fields match: [$CONFIG_OKTA_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_ENTRA_REQUIRED=$(jq -r '."$defs".entra_config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_ENTRA_REQUIRED=$(jq -r '.properties.bifrost.properties.saml.allOf[1].then.properties.config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_ENTRA_REQUIRED" != "$HELM_ENTRA_REQUIRED" ]; then |
| echo "β Entra config required fields mismatch:" |
| echo " Config: [$CONFIG_ENTRA_REQUIRED]" |
| echo " Helm: [$HELM_ENTRA_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Entra config required fields match: [$CONFIG_ENTRA_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking required fields in plugin configs..." |
|
|
| |
| |
| CONFIG_SEMCACHE_REQUIRED=$(jq -r '.properties.plugins.items.allOf[] | select(.if.properties.name.const == "semantic_cache") | .then.properties.config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_SEMCACHE_REQUIRED=$(jq -r '.properties.bifrost.properties.plugins.properties.semanticCache.then.properties.config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_SEMCACHE_REQUIRED" != "$HELM_SEMCACHE_REQUIRED" ]; then |
| echo "β Semantic cache plugin config required fields mismatch:" |
| echo " Config: [$CONFIG_SEMCACHE_REQUIRED]" |
| echo " Helm: [$HELM_SEMCACHE_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Semantic cache plugin config required fields match: [$CONFIG_SEMCACHE_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_OTEL_REQUIRED=$(jq -r '.properties.plugins.items.allOf[] | select(.if.properties.name.const == "otel") | .then.properties.config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_OTEL_REQUIRED=$(jq -r '.properties.bifrost.properties.plugins.properties.otel.then.properties.config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_OTEL_REQUIRED" != "$HELM_OTEL_REQUIRED" ]; then |
| echo "β OTEL plugin config required fields mismatch:" |
| echo " Config: [$CONFIG_OTEL_REQUIRED]" |
| echo " Helm: [$HELM_OTEL_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
OTEL plugin config required fields match: [$CONFIG_OTEL_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_PUSHGW_REQUIRED=$(jq -r '.properties.plugins.items.allOf[] | select(.if.properties.name.const == "telemetry") | .then.properties.config.properties.push_gateway.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_PUSHGW_REQUIRED=$(jq -r '.properties.bifrost.properties.plugins.properties.telemetry.properties.config.properties.push_gateway.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_PUSHGW_REQUIRED" != "$HELM_PUSHGW_REQUIRED" ]; then |
| echo "β Telemetry push_gateway required fields mismatch:" |
| echo " Config: [$CONFIG_PUSHGW_REQUIRED]" |
| echo " Helm: [$HELM_PUSHGW_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Telemetry push_gateway required fields match: [$CONFIG_PUSHGW_REQUIRED]" |
| fi |
|
|
| |
| CONFIG_PUSHGW_AUTH_REQUIRED=$(jq -r '.properties.plugins.items.allOf[] | select(.if.properties.name.const == "telemetry") | .then.properties.config.properties.push_gateway.properties.basic_auth.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_PUSHGW_AUTH_REQUIRED=$(jq -r '.properties.bifrost.properties.plugins.properties.telemetry.properties.config.properties.push_gateway.properties.basic_auth.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_PUSHGW_AUTH_REQUIRED" != "$HELM_PUSHGW_AUTH_REQUIRED" ]; then |
| echo "β Telemetry push_gateway basic_auth required fields mismatch:" |
| echo " Config: [$CONFIG_PUSHGW_AUTH_REQUIRED]" |
| echo " Helm: [$HELM_PUSHGW_AUTH_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Telemetry push_gateway basic_auth required fields match: [$CONFIG_PUSHGW_AUTH_REQUIRED]" |
| fi |
|
|
| |
| |
| CONFIG_PLUGIN_ITEMS_REQUIRED=$(jq -r '.properties.plugins.items.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_PLUGIN_ITEMS_REQUIRED=$(jq -r '.properties.bifrost.properties.plugins.properties.custom.items.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_PLUGIN_ITEMS_REQUIRED" != "$HELM_PLUGIN_ITEMS_REQUIRED" ]; then |
| echo "β Plugin items required fields mismatch:" |
| echo " Config (plugins.items): [$CONFIG_PLUGIN_ITEMS_REQUIRED]" |
| echo " Helm (plugins.custom.items): [$HELM_PLUGIN_ITEMS_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Plugin items required fields match: [$CONFIG_PLUGIN_ITEMS_REQUIRED]" |
| fi |
|
|
| |
| echo "" |
| echo "π Checking plugin item property completeness..." |
|
|
| CONFIG_PLUGIN_PROPS=$(jq -r '.properties.plugins.items.properties | keys | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_CUSTOM_PLUGIN_PROPS=$(jq -r '.properties.bifrost.properties.plugins.properties.custom.items.properties | keys | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| |
| for prop in $(echo "$CONFIG_PLUGIN_PROPS" | tr ',' '\n'); do |
| if ! echo "$HELM_CUSTOM_PLUGIN_PROPS" | tr ',' '\n' | grep -qx "$prop"; then |
| echo "β Plugin property '$prop' exists in config.schema.json but missing from helm custom plugin items" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Plugin property '$prop' present in both schemas" |
| fi |
| done |
|
|
| |
| CONFIG_PLACEMENT_ENUM=$(jq -r '.properties.plugins.items.properties.placement.enum // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_PLACEMENT_ENUM=$(jq -r '.properties.bifrost.properties.plugins.properties.custom.items.properties.placement.enum // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_PLACEMENT_ENUM" != "$HELM_PLACEMENT_ENUM" ]; then |
| echo "β Plugin placement enum mismatch:" |
| echo " Config: [$CONFIG_PLACEMENT_ENUM]" |
| echo " Helm: [$HELM_PLACEMENT_ENUM]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Plugin placement enum values match: [$CONFIG_PLACEMENT_ENUM]" |
| fi |
|
|
| |
| |
| CONFIG_MAXIM_REQUIRED=$(jq -r '.properties.plugins.items.allOf[] | select(.if.properties.name.const == "maxim") | .then.properties.config.required // [] | sort | join(",")' "$CONFIG_SCHEMA" 2>/dev/null || echo "") |
| HELM_MAXIM_REQUIRED=$(jq -r '.properties.bifrost.properties.plugins.properties.maxim.then.anyOf[0].properties.config.required // [] | sort | join(",")' "$HELM_SCHEMA" 2>/dev/null || echo "") |
|
|
| if [ "$CONFIG_MAXIM_REQUIRED" != "$HELM_MAXIM_REQUIRED" ]; then |
| echo "β Maxim plugin config required fields mismatch:" |
| echo " Config: [$CONFIG_MAXIM_REQUIRED]" |
| echo " Helm (anyOf[0]): [$HELM_MAXIM_REQUIRED]" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo "β
Maxim plugin config required fields match: [$CONFIG_MAXIM_REQUIRED]" |
| fi |
|
|
| echo "" |
| echo "π Checking property existence for Gap 1-8 fields..." |
|
|
| |
| check_property_exists() { |
| local label=$1 |
| local jq_path=$2 |
| local schema_file=$3 |
| if ! jq -e "$jq_path" "$schema_file" > /dev/null 2>&1; then |
| echo " β Missing: $label" |
| ERRORS=$((ERRORS + 1)) |
| else |
| echo " β
Present: $label" |
| fi |
| } |
|
|
| |
| echo "" |
| echo " Checking client properties (Gap 1+2)..." |
| for prop in asyncJobResultTTL requiredHeaders loggingHeaders allowedHeaders mcpAgentDepth mcpToolExecutionTimeout mcpCodeModeBindingLevel mcpToolSyncInterval hideDeletedVirtualKeysInFilters; do |
| check_property_exists "client.$prop" ".properties.bifrost.properties.client.properties.${prop}" "$HELM_SCHEMA" |
| done |
|
|
| |
| echo "" |
| echo " Checking OTel plugin properties (Gap 3)..." |
| for prop in headers tls_ca_cert insecure; do |
| check_property_exists "otel.config.$prop" ".properties.bifrost.properties.plugins.properties.otel.properties.config.properties.${prop}" "$HELM_SCHEMA" |
| done |
|
|
| |
| echo "" |
| echo " Checking governance plugin properties (Gap 4)..." |
| for prop in required_headers is_enterprise; do |
| check_property_exists "governance.plugin.config.$prop" ".properties.bifrost.properties.plugins.properties.governance.properties.config.properties.${prop}" "$HELM_SCHEMA" |
| done |
|
|
| |
| echo "" |
| echo " Checking governance top-level properties (Gap 5)..." |
| for prop in modelConfigs providers; do |
| check_property_exists "governance.$prop" ".properties.bifrost.properties.governance.properties.${prop}" "$HELM_SCHEMA" |
| done |
|
|
| |
| echo "" |
| echo " Checking MCP properties (Gap 6)..." |
| check_property_exists "mcp.toolSyncInterval" ".properties.bifrost.properties.mcp.properties.toolSyncInterval" "$HELM_SCHEMA" |
| check_property_exists "mcp.toolManagerConfig.codeModeBindingLevel" '.properties.bifrost.properties.mcp.properties.toolManagerConfig.properties.codeModeBindingLevel' "$HELM_SCHEMA" |
| for prop in clientId isCodeModeClient toolSyncInterval isPingAvailable; do |
| check_property_exists "mcpClientConfig.$prop" '.["$defs"].mcpClientConfig.properties.'"${prop}" "$HELM_SCHEMA" |
| done |
|
|
| |
| echo "" |
| echo " Checking cluster properties (Gap 7)..." |
| check_property_exists "cluster.region" ".properties.bifrost.properties.cluster.properties.region" "$HELM_SCHEMA" |
|
|
| |
| echo "" |
| echo " Checking miscellaneous properties (Gap 8)..." |
| check_property_exists "telemetry.custom_labels" ".properties.bifrost.properties.plugins.properties.telemetry.properties.config.properties.custom_labels" "$HELM_SCHEMA" |
| check_property_exists "semanticCache.default_cache_key" ".properties.bifrost.properties.plugins.properties.semanticCache.properties.config.properties.default_cache_key" "$HELM_SCHEMA" |
|
|
| |
| echo "" |
| echo " Checking config.schema.json has is_ping_available + tool_pricing..." |
| check_property_exists "mcp_client_config.is_ping_available" '."$defs".mcp_client_config.properties.is_ping_available' "$CONFIG_SCHEMA" |
| check_property_exists "mcp_client_config.tool_pricing" '."$defs".mcp_client_config.properties.tool_pricing' "$CONFIG_SCHEMA" |
|
|
| echo "" |
| if [ $ERRORS -gt 0 ]; then |
| echo "β Schema validation failed with $ERRORS error(s)" |
| echo "" |
| echo "To fix these errors, update helm-charts/bifrost/values.schema.json to match" |
| echo "the required fields in transports/config.schema.json" |
| exit 1 |
| fi |
|
|
| echo "β
All schema validations passed!" |
| exit 0 |
|
|