# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 suite: gateway TOML config shape templates: - templates/gateway-config.yaml - templates/deployment.yaml - templates/peer-role.yaml - templates/peer-service.yaml - templates/statefulset.yaml release: name: openshell namespace: my-namespace tests: - it: defaults to label admission with caller driver config disabled template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?m)^allow_driver_config\s*=\s*false$' - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\.resource_admission\]\s*enabled\s*=\s*true' - notMatchRegex: path: data["gateway.toml"] pattern: '\[openshell\.drivers\.kubernetes\.resource_admission\.required_labels\]' - it: preserves explicit admission opt-out without enabling driver config template: templates/gateway-config.yaml set: server.drivers.kubernetes.resourceAdmission.enabled: false asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?m)^allow_driver_config\s*=\s*false$' - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\.resource_admission\]\s*enabled\s*=\s*false' - it: renders replacement labels and literal workspace substitution template: templates/gateway-config.yaml set: server.drivers.kubernetes.allowDriverConfig: true server.drivers.kubernetes.resourceAdmission.requiredLabels: platform.example.com/sandbox-attachable: "approved" platform.example.com/team: '${workspace}' asserts: - matchRegex: path: data["gateway.toml"] pattern: '"platform.example.com/sandbox-attachable" = "approved"' - matchRegex: path: data["gateway.toml"] pattern: '"platform.example.com/team" = "\$\{workspace\}"' - notMatchRegex: path: data["gateway.toml"] pattern: 'openshell.ai/sandbox-attachable' - it: identifies the gateway by chart fullname by default template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?m)^name\s*=\s*"openshell"$' - it: renders an explicit gateway name template: templates/gateway-config.yaml set: server.name: production-us-west asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?m)^name\s*=\s*"production-us-west"$' - it: renders schema version 2 and the Kubernetes compute driver selector template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\]\s*version\s*=\s*2' - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\][^\[]*?compute_driver\s*=\s*"kubernetes"' # Regression for Drew's P2: a ConfigMap-only mutation in `helm upgrade` # must roll the StatefulSet, otherwise pods keep running with stale config. - it: annotates the StatefulSet pod template with a ConfigMap checksum template: templates/statefulset.yaml asserts: - exists: path: spec.template.metadata.annotations["checksum/gateway-config"] - it: mounts gateway.toml as a regular read-only subPath file template: templates/statefulset.yaml asserts: - contains: path: spec.template.spec.containers[0].volumeMounts content: name: gateway-config mountPath: /etc/openshell/gateway.toml subPath: gateway.toml readOnly: true - contains: path: spec.template.spec.volumes content: name: gateway-config configMap: name: openshell-config - it: renders a StatefulSet by default template: templates/statefulset.yaml asserts: - equal: path: kind value: StatefulSet - it: treats a null workload map as the default StatefulSet template: templates/statefulset.yaml set: workload: null asserts: - equal: path: kind value: StatefulSet - it: uses a stable gateway container name template: templates/statefulset.yaml asserts: - equal: path: spec.template.spec.containers[0].name value: openshell-gateway - it: enables anonymous telemetry by default template: templates/statefulset.yaml asserts: - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_TELEMETRY_ENABLED value: "true" - it: disables anonymous telemetry when configured template: templates/statefulset.yaml set: server.telemetryEnabled: false asserts: - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_TELEMETRY_ENABLED value: "false" - it: renders OTLP tracing configuration when configured template: templates/gateway-config.yaml set: server.otlp.endpoint: http://otel-collector.observability.svc:4317 server.otlp.serviceName: production-gateway asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\.otlp\].*?endpoint\s*=\s*"http://otel-collector\.observability\.svc:4317".*?service_name\s*=\s*"production-gateway"' - it: omits OTLP tracing configuration by default template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.otlp\]' - it: renders OIDC transport security settings template: templates/gateway-config.yaml set: server.oidc.issuer: https://issuer.example.com server.oidc.dangerouslyAllowInsecureHttp: false server.oidc.jwksAllowedOrigins[0]: https://keys.example.com asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?m)^dangerously_allow_insecure_http\s*=\s*false$' - matchRegex: path: data["gateway.toml"] pattern: '(?m)^jwks_allowed_origins\s*=\s*\["https://keys.example.com"\]$' - it: treats a null OTLP map as disabled template: templates/gateway-config.yaml set: server.otlp: null asserts: - notMatchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.otlp\]' - it: mounts the OIDC CA bundle when TLS is disabled template: templates/statefulset.yaml set: server.disableTls: true server.oidc.issuer: https://issuer.example.com server.oidc.caConfigMapName: openshell-oidc-ca asserts: - equal: path: spec.template.spec.containers[0].volumeMounts[4].name value: oidc-ca - equal: path: spec.template.spec.containers[0].volumeMounts[4].mountPath value: /etc/openshell-tls/oidc-ca - equal: path: spec.template.spec.volumes[3].name value: oidc-ca - equal: path: spec.template.spec.volumes[3].configMap.name value: openshell-oidc-ca # Regression for the P1 bug Drew flagged: grpc_endpoint MUST live in the # Kubernetes driver table, not in [openshell.gateway]. The gateway-side # schema has `deny_unknown_fields` and no `grpc_endpoint` field, so writing # it at gateway scope makes `config_file::load` reject the default install. - it: renders grpc_endpoint under [openshell.drivers.kubernetes], not [openshell.gateway] template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?grpc_endpoint' - notMatchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\][^\[]*?grpc_endpoint' - it: omits pull policies by default so Kubernetes applies its own defaults template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: '(?m)^\s*(image_pull_policy|supervisor_image_pull_policy)\s*=' - it: renders canonical image pull policies in the Kubernetes driver table template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: if_not_present supervisor.image.pullPolicy: never asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?image_pull_policy\s*=\s*"if_not_present".*?supervisor_image_pull_policy\s*=\s*"never"' - it: translates legacy Kubernetes pull policy values to canonical gateway values template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: Always supervisor.image.pullPolicy: IfNotPresent asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?image_pull_policy\s*=\s*"always".*?supervisor_image_pull_policy\s*=\s*"if_not_present"' - it: rejects unsupported sandbox image pull policies template: templates/statefulset.yaml set: server.sandboxImagePullPolicy: Sometimes asserts: - failedTemplate: errorMessage: 'image pull policy "Sometimes" must be one of: always, if_not_present, never, Always, IfNotPresent, Never' - it: rejects unsupported supervisor image pull policies template: templates/statefulset.yaml set: supervisor.image.pullPolicy: newer asserts: - failedTemplate: errorMessage: 'image pull policy "newer" must be one of: always, if_not_present, never, Always, IfNotPresent, Never' - it: renders driver-owned Kubernetes settings only in its driver table template: templates/gateway-config.yaml set: server.hostGatewayIP: 10.0.0.1 server.enableUserNamespaces: true supervisor.image.tag: test asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?namespace\s*=\s*"my-namespace".*?default_image\s*=.*?supervisor_image\s*=.*?host_gateway_ip\s*=\s*"10\.0\.0\.1".*?client_tls_secret_name\s*=.*?service_account_name\s*=\s*"openshell-sandbox".*?enable_user_namespaces\s*=\s*true.*?sa_token_ttl_secs\s*=' - notMatchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\][^\[]*?(sandbox_namespace|default_image|supervisor_image|client_tls_secret_name|service_account_name|host_gateway_ip|enable_user_namespaces|sa_token_ttl_secs)\s*=' - notMatchRegex: path: data["gateway.toml"] pattern: 'guest_tls_(ca|cert|key)\s*=' - it: renders user namespace enablement under [openshell.drivers.kubernetes] template: templates/gateway-config.yaml set: server.enableUserNamespaces: true asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?enable_user_namespaces\s*=\s*true' - notMatchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\][^\[]*?enable_user_namespaces' - it: renders operator-owned upstream proxy settings under the Kubernetes driver template: templates/gateway-config.yaml set: upstreamProxy.url: http://proxy.corp.example:8080 upstreamProxy.noProxy: .svc.cluster.local,10.96.0.0/12 upstreamProxy.authSecret.name: corporate-proxy-auth upstreamProxy.authSecret.key: credentials upstreamProxy.authAllowInsecure: true upstreamProxy.connectByHostname: true asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?https_proxy\s*=\s*"http://proxy\.corp\.example:8080"' - matchRegex: path: data["gateway.toml"] pattern: 'proxy_auth_secret_name\s*=\s*"corporate-proxy-auth"' - matchRegex: path: data["gateway.toml"] pattern: 'proxy_auth_secret_key\s*=\s*"credentials"' - matchRegex: path: data["gateway.toml"] pattern: 'proxy_auth_allow_insecure\s*=\s*true' - matchRegex: path: data["gateway.toml"] pattern: 'no_proxy\s*=\s*"\.svc\.cluster\.local,10\.96\.0\.0/12"' - matchRegex: path: data["gateway.toml"] pattern: 'proxy_connect_by_hostname\s*=\s*true' - it: renders proxy_ca_bundle when a corporate CA ConfigMap is configured template: templates/gateway-config.yaml set: upstreamProxy.url: https://proxy.corp.example:3130 upstreamProxy.caBundle.configMapName: corporate-proxy-ca asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?proxy_ca_bundle\s*=\s*"/etc/openshell-tls/proxy-ca/ca\.crt"' - it: omits proxy_ca_bundle when no corporate CA ConfigMap is configured template: templates/gateway-config.yaml set: upstreamProxy.url: http://proxy.corp.example:8080 asserts: - notMatchRegex: path: data["gateway.toml"] pattern: 'proxy_ca_bundle\s*=' - it: uses the gateway built-in supervisor image by default template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: 'supervisor_image\s*=' - it: uses the gateway built-in sandbox runtime image by default template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: 'sandbox_runtime_image\s*=' - it: renders independent sandbox runtime and supervisor image overrides template: templates/gateway-config.yaml set: sandboxRuntime.image.repository: registry.example.com/openshell/sandbox sandboxRuntime.image.tag: sandbox-build sandboxRuntime.image.pullPolicy: Always supervisor.image.repository: registry.example.com/openshell/supervisor supervisor.image.tag: supervisor-build asserts: - matchRegex: path: data["gateway.toml"] pattern: 'sandbox_runtime_image\s*=\s*"registry\.example\.com/openshell/sandbox:sandbox-build"' - matchRegex: path: data["gateway.toml"] pattern: 'sandbox_runtime_image_pull_policy\s*=\s*"always"' - matchRegex: path: data["gateway.toml"] pattern: 'supervisor_image\s*=\s*"registry\.example\.com/openshell/supervisor:supervisor-build"' - it: renders a supervisor tag override with the official repository template: templates/gateway-config.yaml set: supervisor.image.tag: 1.2.3 asserts: - matchRegex: path: data["gateway.toml"] pattern: 'supervisor_image\s*=\s*"ghcr\.io/nvidia/openshell/supervisor:1\.2\.3"' - it: renders a supervisor repository override with the effective gateway tag template: templates/gateway-config.yaml set: image.tag: gateway-build supervisor.image.repository: registry.example.com/openshell/supervisor asserts: - matchRegex: path: data["gateway.toml"] pattern: 'supervisor_image\s*=\s*"registry\.example\.com/openshell/supervisor:gateway-build"' - it: renders complete supervisor repository and tag overrides template: templates/gateway-config.yaml set: supervisor.image.repository: registry.example.com/openshell/supervisor supervisor.image.tag: supervisor-build asserts: - matchRegex: path: data["gateway.toml"] pattern: 'supervisor_image\s*=\s*"registry\.example\.com/openshell/supervisor:supervisor-build"' - it: configures managed SSH isolation with the gateway peer template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\.managed_ssh_ingress\].*?enabled\s*=\s*true.*?gateway_namespace\s*=\s*"my-namespace".*?gateway_pod_selector\s*=.*?app\.kubernetes\.io/name.*?openshell' - it: renders sandbox image pull secrets under [openshell.drivers.kubernetes] template: templates/gateway-config.yaml set: server.sandboxImagePullSecrets: - name: regcred - name: backup-regcred asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?image_pull_secrets\s*=\s*\["regcred", "backup-regcred"\]' - it: does not reuse gateway image pull secrets for sandbox pods template: templates/gateway-config.yaml set: imagePullSecrets: - name: gateway-regcred asserts: - notMatchRegex: path: data["gateway.toml"] pattern: 'image_pull_secrets\s*=' - it: does not render local mTLS user auth for Kubernetes deployments template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.mtls_auth\]' - it: does not allow unauthenticated users by default template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.auth\]' - it: renders explicit unauthenticated user dev mode when enabled template: templates/gateway-config.yaml set: server.auth.allowUnauthenticatedUsers: true asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\.auth\].*?allow_unauthenticated_users\s*=\s*true' - it: omits the gRPC rate limit by default template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: 'grpc_rate_limit_requests\s*=' - notMatchRegex: path: data["gateway.toml"] pattern: 'grpc_rate_limit_window_seconds\s*=' - it: renders fail-closed policy validation posture by default template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\].*?policy_validation_failure_mode\s*=\s*"fail_closed"' - it: renders retain-last-valid policy validation posture template: templates/gateway-config.yaml set: server.policyValidationFailureMode: retain_last_valid asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\].*?policy_validation_failure_mode\s*=\s*"retain_last_valid"' - it: renders the gRPC rate limit under [openshell.gateway] when both values are positive template: templates/gateway-config.yaml set: server.grpcRateLimit.requests: 120 server.grpcRateLimit.windowSeconds: 60 asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\].*?grpc_rate_limit_requests\s*=\s*120' - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\].*?grpc_rate_limit_window_seconds\s*=\s*60' # The validation lives in gateway-config.yaml but surfaces through the # statefulset checksum include, so the failure is asserted against that # template (mirrors the postgres serviceBindings failure test below). - it: fails to render when only requests is positive template: templates/statefulset.yaml set: server.grpcRateLimit.requests: 120 asserts: - failedTemplate: errorMessage: "server.grpcRateLimit requires both requests and windowSeconds to be positive to enable rate limiting, or both 0/unset to disable it" - it: fails to render when only windowSeconds is positive template: templates/statefulset.yaml set: server.grpcRateLimit.windowSeconds: 60 asserts: - failedTemplate: errorMessage: "server.grpcRateLimit requires both requests and windowSeconds to be positive to enable rate limiting, or both 0/unset to disable it" - it: fails to render when requests is negative template: templates/statefulset.yaml set: server.grpcRateLimit.requests: -1 asserts: - failedTemplate: errorMessage: "server.grpcRateLimit.requests and server.grpcRateLimit.windowSeconds must not be negative; they map to unsigned gateway settings" - it: fails to render when windowSeconds is negative template: templates/statefulset.yaml set: server.grpcRateLimit.windowSeconds: -5 asserts: - failedTemplate: errorMessage: "server.grpcRateLimit.requests and server.grpcRateLimit.windowSeconds must not be negative; they map to unsigned gateway settings" - it: uses the configured existing sandbox service account name template: templates/gateway-config.yaml set: sandboxServiceAccount.create: false sandboxServiceAccount.name: precreated-sandbox asserts: - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.drivers\.kubernetes\].*?service_account_name\s*=\s*"precreated-sandbox"' - it: omits server_sans when no DNS SANs are configured template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: 'server_sans\s*=' - it: emits disable_tls=true and omits the [openshell.gateway.tls] section when disableTls is set set: server.disableTls: true certManager.enabled: false pkiInitJob.enabled: false template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: 'disable_tls\s*=\s*true' - notMatchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.tls\]' - it: omits client_ca_path from the TLS section when mTLS is disabled template: templates/gateway-config.yaml set: server.tls.enableMtls: false asserts: - matchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.tls\]' - matchRegex: path: data["gateway.toml"] pattern: 'cert_path\s*=' - matchRegex: path: data["gateway.toml"] pattern: 'key_path\s*=' - notMatchRegex: path: data["gateway.toml"] pattern: 'client_ca_path\s*=' - it: renders client_ca_path for built-in PKI by default template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: 'client_ca_path\s*=\s*"/etc/openshell-tls/client-ca/ca\.crt"' - it: omits client_ca_path when clientCaSecretName is empty for HTTPS-only mode template: templates/gateway-config.yaml set: server.tls.clientCaSecretName: "" asserts: - matchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.tls\]' - matchRegex: path: data["gateway.toml"] pattern: 'cert_path\s*=\s*"/etc/openshell-tls/server/tls\.crt"' - matchRegex: path: data["gateway.toml"] pattern: 'key_path\s*=\s*"/etc/openshell-tls/server/tls\.key"' - notMatchRegex: path: data["gateway.toml"] pattern: 'client_ca_path\s*=' - it: keeps external server certificate fields when clientCaSecretName is empty template: templates/gateway-config.yaml set: certManager.enabled: true certManager.serverIssuerRef.name: letsencrypt-prod certManager.serverDnsNames: - gateway.example.com server.tls.clientCaSecretName: "" asserts: - notMatchRegex: path: data["gateway.toml"] pattern: 'client_ca_path\s*=' - matchRegex: path: data["gateway.toml"] pattern: 'external_cert_path\s*=\s*"/etc/openshell-tls/server-external/tls\.crt"' - matchRegex: path: data["gateway.toml"] pattern: 'external_key_path\s*=\s*"/etc/openshell-tls/server-external/tls\.key"' - matchRegex: path: data["gateway.toml"] pattern: 'external_server_names\s*=\s*\["gateway\.example\.com"\]' - it: omits client_ca_path for cert-manager shared CA when clientCaSecretName is empty template: templates/gateway-config.yaml set: certManager.enabled: true certManager.clientCaFromServerTlsSecret: true server.tls.clientCaSecretName: "" asserts: - matchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.tls\]' - matchRegex: path: data["gateway.toml"] pattern: 'cert_path\s*=\s*"/etc/openshell-tls/server/tls\.crt"' - matchRegex: path: data["gateway.toml"] pattern: 'key_path\s*=\s*"/etc/openshell-tls/server/tls\.key"' - notMatchRegex: path: data["gateway.toml"] pattern: 'client_ca_path\s*=' - it: omits client_ca_path when cert-manager owns TLS and no client CA secret is set template: templates/gateway-config.yaml set: certManager.enabled: true certManager.clientCaFromServerTlsSecret: false pkiInitJob.enabled: true server.tls.clientCaSecretName: "" asserts: - matchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.tls\]' - matchRegex: path: data["gateway.toml"] pattern: 'cert_path\s*=\s*"/etc/openshell-tls/server/tls\.crt"' - matchRegex: path: data["gateway.toml"] pattern: 'key_path\s*=\s*"/etc/openshell-tls/server/tls\.key"' - notMatchRegex: path: data["gateway.toml"] pattern: 'client_ca_path\s*=' - it: renders server_sans from certManager.serverDnsNames set: certManager.enabled: true certManager.serverDnsNames: - openshell - "*.dev.openshell.localhost" pkiInitJob.enabled: false template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: 'server_sans\s*=\s*\["openshell", "\*\.dev\.openshell\.localhost"\]' - it: passes sqlite db-url via --db-url arg by default template: templates/statefulset.yaml asserts: - contains: path: spec.template.spec.containers[0].args content: "sqlite:/var/openshell/openshell.db" - it: fails when clientCaSecretName is null template: templates/statefulset.yaml set: server.tls.clientCaSecretName: null asserts: - failedTemplate: errorMessage: "server.tls.clientCaSecretName cannot be null; omit the key to use the chart default (openshell-server-client-ca), or set to \"\" to disable client certificate verification for HTTPS-only mode" - it: configures gateway peer identity and projected peer token template: templates/statefulset.yaml asserts: - equal: path: spec.serviceName value: openshell-peer - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_SERVICE_NAME value: openshell-peer - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_TOKEN_AUDIENCE value: openshell-gateway-peer - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_TLS_SERVER_NAME value: openshell.my-namespace.svc.cluster.local - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_TLS_CA_FILE value: /etc/openshell-tls/server/ca.crt - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_TLS_CERT_FILE value: /etc/openshell-tls/peer-client/tls.crt - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_TLS_KEY_FILE value: /etc/openshell-tls/peer-client/tls.key - contains: path: spec.template.spec.containers[0].volumeMounts content: name: gateway-peer-token mountPath: /var/run/secrets/openshell-peer readOnly: true - contains: path: spec.template.spec.containers[0].volumeMounts content: name: peer-client-tls mountPath: /etc/openshell-tls/peer-client readOnly: true - equal: path: spec.template.spec.volumes[2].projected.sources[0].serviceAccountToken.audience value: openshell-gateway-peer - it: configures gateway peer identity and projected peer token for Deployment template: templates/deployment.yaml set: workload.kind: deployment server.externalDbSecret: my-pg-secret server.disableTls: true asserts: - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_POD_IP valueFrom: fieldRef: fieldPath: status.podIP - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_ENDPOINT value: http://$(OPENSHELL_POD_IP):8080 - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_SERVICE_NAME value: openshell-peer - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_PEER_TOKEN_AUDIENCE value: openshell-gateway-peer - contains: path: spec.template.spec.containers[0].volumeMounts content: name: gateway-peer-token mountPath: /var/run/secrets/openshell-peer readOnly: true - equal: path: spec.template.spec.volumes[2].projected.sources[0].serviceAccountToken.audience value: openshell-gateway-peer - it: renders headless gateway peer service template: templates/peer-service.yaml asserts: - equal: path: metadata.name value: openshell-peer - equal: path: spec.clusterIP value: None - equal: path: spec.publishNotReadyAddresses value: true - it: grants release-namespace pod lookup for gateway peer identity validation template: templates/peer-role.yaml asserts: - hasDocuments: count: 2 - equal: path: metadata.namespace value: my-namespace documentIndex: 0 - equal: path: rules[0].resources[0] value: pods documentIndex: 0 - equal: path: subjects[0].name value: openshell documentIndex: 1 - it: fails when legacy postgres.enabled is set template: templates/statefulset.yaml set: postgres.enabled: true asserts: - failedTemplate: errorPattern: "postgres.enabled was removed" - it: fails when multiple replicas use the default SQLite database template: templates/statefulset.yaml set: replicaCount: 2 asserts: - failedTemplate: errorPattern: "replicaCount > 1 requires server.externalDbSecret" - it: renders a Deployment for external database-backed gateway workloads template: templates/deployment.yaml set: workload.kind: deployment replicaCount: 2 server.externalDbSecret: my-pg-secret server.credentialDrivers.kubernetesSecrets.enabled: true asserts: - equal: path: kind value: Deployment - equal: path: spec.replicas value: 2 - equal: path: spec.template.spec.containers[0].name value: openshell-gateway - contains: path: spec.template.spec.containers[0].volumeMounts content: name: gateway-config mountPath: /etc/openshell/gateway.toml subPath: gateway.toml readOnly: true - notContains: path: spec.template.spec.containers[0].volumeMounts content: name: openshell-data mountPath: /var/openshell - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_DB_URL valueFrom: secretKeyRef: name: my-pg-secret key: uri - it: fails when a Deployment uses the default SQLite database template: templates/statefulset.yaml set: workload.kind: deployment asserts: - failedTemplate: errorPattern: "workload.kind=deployment requires server.externalDbSecret" - it: fails when multiple replicas use a StatefulSet without an override template: templates/statefulset.yaml set: replicaCount: 2 server.externalDbSecret: my-pg-secret asserts: - failedTemplate: errorPattern: "replicaCount > 1 with workload.kind=statefulset requires workload.allowMultiReplicaStatefulSet=true" - it: allows a multi-replica StatefulSet with an external database and explicit override template: templates/statefulset.yaml set: replicaCount: 2 server.externalDbSecret: my-pg-secret workload.allowMultiReplicaStatefulSet: true server.credentialDrivers.kubernetesSecrets.enabled: true asserts: - equal: path: kind value: StatefulSet - equal: path: spec.replicas value: 2 - contains: path: spec.template.spec.containers[0].volumeMounts content: name: openshell-data mountPath: /var/openshell - it: fails when workload.kind is invalid template: templates/statefulset.yaml set: workload.kind: daemonset asserts: - failedTemplate: errorPattern: "workload.kind must be one of: statefulset, deployment" - it: does not pass --db-url in args when externalDbSecret is set template: templates/statefulset.yaml set: server.externalDbSecret: my-pg-secret asserts: - notContains: path: spec.template.spec.containers[0].args content: "--db-url" - it: references externalDbSecret when set template: templates/statefulset.yaml set: server.externalDbSecret: my-pg-secret asserts: - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_DB_URL valueFrom: secretKeyRef: name: my-pg-secret key: uri - it: renders HA external database configuration from the CI overlay as a Deployment template: templates/deployment.yaml values: - ../ci/values-high-availability.yaml asserts: - equal: path: kind value: Deployment - equal: path: spec.replicas value: 2 - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_DB_URL valueFrom: secretKeyRef: name: openshell-ha-pg key: uri - it: renders provider SPIFFE token grants while keeping gateway JWT auth set: server.providerTokenGrants.spiffe.enabled: true template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.gateway_jwt\]' - matchRegex: path: data["gateway.toml"] pattern: 'provider_spiffe_workload_api_socket_path\s*=\s*"/spiffe-workload-api/spire-agent\.sock"' - notMatchRegex: path: data["gateway.toml"] pattern: '\[openshell\.gateway\.spiffe\]' - it: mounts the gateway SPIFFE socket while keeping sandbox JWT auth set: server.providerTokenGrants.spiffe.enabled: true template: templates/statefulset.yaml asserts: - contains: path: spec.template.spec.containers[0].env content: name: OPENSHELL_GATEWAY_SPIFFE_WORKLOAD_API_SOCKET value: /spiffe-workload-api/spire-agent.sock - contains: path: spec.template.spec.containers[0].volumeMounts content: name: sandbox-jwt mountPath: /etc/openshell-jwt readOnly: true - contains: path: spec.template.spec.containers[0].volumeMounts content: name: spiffe-workload-api mountPath: /spiffe-workload-api readOnly: true - contains: path: spec.template.spec.volumes content: name: sandbox-jwt secret: defaultMode: 256 secretName: openshell-jwt-keys - contains: path: spec.template.spec.volumes content: name: spiffe-workload-api csi: driver: csi.spiffe.io readOnly: true - it: fails when serverIssuerRef is set but certManager is disabled template: templates/statefulset.yaml set: certManager.serverIssuerRef.name: letsencrypt-prod certManager.enabled: false asserts: - failedTemplate: errorMessage: "certManager.serverIssuerRef.name is set but certManager.enabled is false \u2014 the external server certificate, its Secret mount, and the gateway TLS configuration all require cert-manager to be enabled. Set certManager.enabled=true or remove certManager.serverIssuerRef.name." - it: does not render the schema-v1 compute_drivers selector template: templates/gateway-config.yaml asserts: - notMatchRegex: path: data["gateway.toml"] pattern: "(?m)^\\s*compute_drivers\\s*=" - it: uses the release fullname and namespace for default Kubernetes settings template: templates/gateway-config.yaml asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)name\\s*=\\s*\\\"openshell\\\".*?\\[openshell\\.drivers\\.kubernetes\\].*?namespace\\s*=\\s*\\\"my-namespace\\\".*?grpc_endpoint\\s*=\\s*\\\"https://openshell\\.my-namespace\\.svc\\.cluster\\.local:8080\\\"" - it: uses an explicit server grpc endpoint verbatim template: templates/gateway-config.yaml set: server.grpcEndpoint: https://gateway.example.test:9443 asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?grpc_endpoint\\s*=\\s*\\\"https://gateway\\.example\\.test:9443\\\"" - it: uses HTTP callback and omits client TLS secret when TLS is disabled template: templates/gateway-config.yaml set: server.disableTls: true asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?grpc_endpoint\\s*=\\s*\\\"http://openshell\\.my-namespace\\.svc\\.cluster\\.local:8080\\\"" - notMatchRegex: path: data["gateway.toml"] pattern: "client_tls_secret_name\\s*=" - it: accepts Always pull policy spelling for sandbox and supervisor template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: Always supervisor.image.pullPolicy: Always asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?image_pull_policy\\s*=\\s*\\\"always\\\".*?supervisor_image_pull_policy\\s*=\\s*\\\"always\\\"" - it: accepts IfNotPresent pull policy spelling for sandbox and supervisor template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: IfNotPresent supervisor.image.pullPolicy: IfNotPresent asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?image_pull_policy\\s*=\\s*\\\"if_not_present\\\".*?supervisor_image_pull_policy\\s*=\\s*\\\"if_not_present\\\"" - it: accepts Never pull policy spelling for sandbox and supervisor template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: Never supervisor.image.pullPolicy: Never asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?image_pull_policy\\s*=\\s*\\\"never\\\".*?supervisor_image_pull_policy\\s*=\\s*\\\"never\\\"" - it: accepts canonical lowercase pull policies for sandbox and supervisor template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: always supervisor.image.pullPolicy: always asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?image_pull_policy\\s*=\\s*\\\"always\\\".*?supervisor_image_pull_policy\\s*=\\s*\\\"always\\\"" - it: accepts canonical if_not_present pull policies for sandbox and supervisor template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: if_not_present supervisor.image.pullPolicy: if_not_present asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?image_pull_policy\\s*=\\s*\\\"if_not_present\\\".*?supervisor_image_pull_policy\\s*=\\s*\\\"if_not_present\\\"" - it: accepts canonical never pull policies for sandbox and supervisor template: templates/gateway-config.yaml set: server.sandboxImagePullPolicy: never supervisor.image.pullPolicy: never asserts: - matchRegex: path: data["gateway.toml"] pattern: "(?ms)\\[openshell\\.drivers\\.kubernetes\\].*?image_pull_policy\\s*=\\s*\\\"never\\\".*?supervisor_image_pull_policy\\s*=\\s*\\\"never\\\""