Files
OpenShell/deploy/helm/openshell/tests/gateway_config_test.yaml
Drew Newberry c1f2e7189f feat(isolation): implement the RFC 0012 sandbox architecture (#2942)
* feat(isolation): add RFC 0012 backend contract

Signed-off-by: Drew Newberry <385+drew@users.noreply.github.com>

* refactor(isolation): name the interface crate explicitly

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): expose trusted host gateway

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs(agents): inventory the MXC driver

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): add mediated DNS transport

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): tighten interface error and digest contracts

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs(isolation): remove unrelated driver inventory

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): define capability-free launch contract

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): seal confirmed boundary state

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): validate confirmation for external backend implementations

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): clarify mediated DNS identity

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(isolation): generalize loopback connector

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(isolation): unify typed network mediation

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): bind launches to sandbox sessions

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(mxc): initialize extended sandbox status

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): add boundary protocol and Linux primitives

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): harden signals and separate process status from transport

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): validate remote confirmation through public contract

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): validate wire state and propagate snapshot failures

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* test(isolation): import owned agent specification explicitly

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs(isolation): describe mediated DNS channel

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): bound mediation attach without nested retries

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(isolation): generalize loopback protocol

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): add transport-neutral session authentication

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(isolation): separate sandbox backend protocol

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): harden runtime boundary controls

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): add terminal boundary operation

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): split supervisor and sandbox runtimes

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): harden boundary isolation and lifecycle ownership

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): reject private root redirects and adopt typed errors

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): preserve accept thread ownership on musl

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* test(sandbox): isolate credential probes from filtered threads

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): return retained exec exit status to independent waiters

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): bound network mediation and preserve socket authorization

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): bound control admission and retire stale mediation

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* ci(e2e): select migrated drivers per stack layer

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(sandbox): implement loopback connector

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(isolation): authenticate the Sandbox Protocol

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(supervisor): rotate launch-scoped authentication

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(sandbox): consume dedicated backend crate

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* test(sandbox): align topology session fixture

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): align projected bootstrap bundle

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(auth): validate refreshed credentials before rotation

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): fail closed across supervisor disconnects

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): repair rebased sandbox CI

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* build(runtime): publish separate sandbox and supervisor images

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(config): configure the sandbox runtime image

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(ci): validate sandbox binary linkage

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(isolation): use backend and runtime terminology

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(sandbox): use a scratch runtime image

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(ci): refresh schema and dependency policy

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(sandbox): bind reconnects to supervisor process

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs: align runtime split operational guidance

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* chore(security): document Kubernetes runtime RBAC

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): enforce runtime lifecycle invariants

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(compute): identify sandbox start generations

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(server): restore sandbox launch sessions

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): support authenticated runtime replacement

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(auth): bind sandbox session successors

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(auth): retry pending sandbox successors

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(vm): run the supervisor outside the guest workload

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(vm): use sandbox backend protocol

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): repair rebase integration

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): use unified build toolchain

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(vm): use sandbox runtime terminology

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(vm): own guest network bootstrap

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): expose guest init version

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): select native supervisor artifacts

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): guard guest init Linux symbols

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): scope Linux test imports

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): avoid guest interface casts

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): reconcile admitted sandbox identity

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): share resolved sandbox identity

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): surface host supervisor failures

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): include guest logs on supervisor exit

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): rotate and clean runtime generations

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): make sandbox starts generation-aware

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): rotate restored sandbox sessions

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(vm): keep shared paths in the base layer

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): bind sandbox session lineage

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(docker): isolate workloads behind the host supervisor

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(docker): rotate launch-scoped authentication

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(docker): use sandbox backend protocol

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(docker): use host networking for supervisor

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): preserve host gateway alias resolution

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(docker): use separate sandbox and supervisor images

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): restore startup validation after rebase

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(docker): name the sandbox runtime directly

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): narrow supervisor CA runtime storage

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): close companion isolation gaps

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* test(docker): align mediated network expectations

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* test(docker): exercise mediated network paths

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): attach supervisor to managed network

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): defer supervisor recovery until gateway is ready

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): make sandbox starts generation-aware

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): rotate restored sandbox sessions

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): preserve workloads during session rotation

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(docker): remove unrelated configuration RFC changes

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): bind sandbox session lineage

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(kubernetes): add proxy-pod isolation topology

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(kubernetes): use sandbox backend protocol

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): use stable sandbox service authority

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(kubernetes): split sandbox and supervisor images

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): adapt proxy pods to current runtime APIs

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(kubernetes): describe the single runtime placement

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(kubernetes): simplify sandbox orchestration

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): validate deployment prerequisites

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): update Trivy Helm profile inventory

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* test(kubernetes): update Trivy scan inventory count

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): reuse preloaded runtime images in e2e

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): type and clean runtime resources

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): make sandbox restarts recoverable

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): rotate restored sandbox sessions

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): preserve supervisor egress

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): bind sandbox session lineage

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(podman): adopt isolated sandbox and supervisor containers

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): stage bootstrap archives at named volume destinations

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(podman): rotate launch-scoped authentication

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(podman): use sandbox backend protocol

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(podman): use host networking for supervisor

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(podman): split sandbox and supervisor images

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): repair rebase integration

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(podman): name the sandbox runtime directly

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): provision supervisor CA runtime storage

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): address isolation review findings

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): inspect Debian supervisor provenance

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): use libpod-compatible tmpfs options

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): bind verified sandbox runtime binary

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): provide external driver data directory

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): start sandbox before joining user namespace

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): separate supervisor user namespace

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): make sandbox starts generation-aware

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): rotate restored sandbox sessions

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): bind sandbox session lineage

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* perf(isolation): add TCP and DNS benchmark harnesses

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(perf): align benchmark timing and supported protocols

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(perf): report TCP benchmark metrics accurately

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(perf): cancel failed worker startup

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(docker): build matching local supervisor image

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(podman): make local sandbox smoke test runnable

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): wire local sandbox runtime image

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(kubernetes): narrow sandbox service RBAC

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(ci): validate split runtime artifacts

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): harden runtime session handling

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* feat(supervisor): add standalone network proxy role

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* docs(rfc): remove implementation companion notes

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* refactor(vm): standardize runtime release name

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(vm): pin renamed runtime artifacts

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(auth): persist sandbox runtime identity

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(runtime): restore branch validation

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(isolation): reconcile main after rebase

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(network): close unframed HTTP 1.0 responses

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* chore(isolation): preserve upstream OCSF updates

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(security): close credential and TLS replay paths

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

* fix(auth): make sandbox refresh retries idempotent

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

---------

Signed-off-by: Drew Newberry <385+drew@users.noreply.github.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
2026-09-16 00:49:14 +00:00

931 lines
34 KiB
YAML

# 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/statefulset.yaml
release:
name: openshell
namespace: my-namespace
tests:
- 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[3].name
value: oidc-ca
- equal:
path: spec.template.spec.containers[0].volumeMounts[3].mountPath
value: /etc/openshell-tls/oidc-ca
- equal:
path: spec.template.spec.volumes[2].name
value: oidc-ca
- equal:
path: spec.template.spec.volumes[2].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: 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: 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\\\""