diff --git a/.agents/skills/debug-openshell-cluster/SKILL.md b/.agents/skills/debug-openshell-cluster/SKILL.md index 319031b1d1..2c44295185 100644 --- a/.agents/skills/debug-openshell-cluster/SKILL.md +++ b/.agents/skills/debug-openshell-cluster/SKILL.md @@ -457,6 +457,7 @@ openshell logs | Supervisor enters policy quarantine | A runtime candidate failed validation while `policy_validation_failure_mode = "fail_closed"` | Sandbox OCSF config/finding events, validation rationale, active generation, `previous_policy_active` | | HTTP request returns `middleware_failed` or `middleware_denied` | Selected stage failed or explicitly denied the admitted request | Sandbox OCSF logs; policy-local middleware config; service availability; `on_error` | | Custom compute driver is unavailable | Driver process/socket missing, inaccessible, or configured with a reserved/mismatched name | Socket ownership/mode, driver service logs, gateway `GetCapabilities` logs | +| Sandbox remains `Suspending` or `Resuming` | Driver stop/start failed, retained resource is missing, or the resumed supervisor has not reconnected | Gateway and driver logs; `docker inspect`, `podman inspect`, Agent Sandbox status/PVC, or VM state marker and launcher process | | Image pull failure | Gateway or sandbox image cannot be pulled | Runtime events and image pull credentials | | `K8s namespace not ready` with `envoy-gateway-openshell.yaml: the server could not find the requested resource` | Optional Gateway API manifest was applied without Envoy Gateway CRDs, or k3s Helm controller startup exceeded the namespace wait | Apply `deploy/kube/manifests/envoy-gateway-openshell.yaml` manually only after Envoy Gateway is installed and `grpcRoute` is enabled | | HTTPS ingress (`grpcRoute.gateway.listener.protocol=HTTPS`) connection resets or TLS handshake hangs | Envoy terminates TLS but the gateway pod still expects TLS, so the plaintext backend hop fails | Set `server.disableTls=true` so Envoy forwards plaintext to the pod; verify the listener `certificateRefs` Secret exists in the release namespace and `openshell status` over `https://` | diff --git a/.agents/skills/openshell-cli/SKILL.md b/.agents/skills/openshell-cli/SKILL.md index 866e57008a..0aa70efce5 100644 --- a/.agents/skills/openshell-cli/SKILL.md +++ b/.agents/skills/openshell-cli/SKILL.md @@ -283,6 +283,21 @@ openshell sandbox delete sandbox-1 sandbox-2 sandbox-3 # Multiple at once openshell sandbox delete --all ``` +### Suspend and resume sandboxes + +Use suspension to stop compute while retaining the sandbox and its persistent +workspace: + +```bash +openshell sandbox suspend [name] +openshell sandbox resume [name] +``` + +Both commands default to the last-used sandbox. Suspend stops background +forwards and waits for `Suspended`; resume waits for `Ready`. Connect, exec, +file transfer, forwarding, and exposed services are unavailable while +suspended. Delete remains the operation that removes retained state. + --- ## Workflow 4: Policy Iteration Loop @@ -636,7 +651,7 @@ The CLI help is always authoritative. If the help output contradicts this skill, ```bash $ openshell sandbox --help -# Shows: create, get, list, delete, exec, connect, upload, download, ssh-config, provider +# Shows: create, get, list, suspend, resume, delete, exec, connect, upload, download, ssh-config, provider $ openshell sandbox upload --help # Shows: positional arguments (name, path, dest), usage examples @@ -658,6 +673,8 @@ $ openshell sandbox upload --help | Create sandbox with GPUs | `openshell sandbox create --gpu 1` | | Create with custom policy | `openshell sandbox create --policy ./p.yaml` | | Connect to sandbox | `openshell sandbox connect ` | +| Suspend sandbox compute | `openshell sandbox suspend [name]` | +| Resume sandbox compute | `openshell sandbox resume [name]` | | Execute in sandbox | `openshell sandbox exec --name -- ` | | Stream live logs | `openshell logs --tail` | | Incremental policy update | `openshell policy update --add-endpoint host:443:read-only:rest:enforce --binary /usr/bin/curl --wait` | diff --git a/.agents/skills/openshell-cli/cli-reference.md b/.agents/skills/openshell-cli/cli-reference.md index 30d6fb7ed3..801cf09ea2 100644 --- a/.agents/skills/openshell-cli/cli-reference.md +++ b/.agents/skills/openshell-cli/cli-reference.md @@ -48,6 +48,8 @@ openshell │ ├── create [opts] [-- CMD...] │ ├── get [name] │ ├── list [opts] +│ ├── suspend [name] +│ ├── resume [name] │ ├── delete [name]... [--all] │ ├── exec [--name ] [opts] -- CMD... │ ├── connect [name] [--editor ] @@ -250,6 +252,17 @@ Show sandbox details and the active policy. Metadata identifies sandbox or globa Delete one or more named sandboxes, or use `--all`. Deletion stops background port forwards. +### `openshell sandbox suspend [name]` + +Stop sandbox compute while retaining the sandbox and persistent workspace. The +name defaults to the last-used sandbox. The command stops background forwards +and waits for the `Suspended` phase. + +### `openshell sandbox resume [name]` + +Restart a suspended sandbox and wait for `Ready`. The name defaults to the +last-used sandbox. + ### `openshell sandbox exec [OPTIONS] -- COMMAND...` Execute a command through the gRPC exec endpoint, stream its output, and exit with the remote command's exit code. diff --git a/architecture/compute-runtimes.md b/architecture/compute-runtimes.md index 646b6320bd..7bf8ac5974 100644 --- a/architecture/compute-runtimes.md +++ b/architecture/compute-runtimes.md @@ -1,6 +1,6 @@ # Compute Runtimes -Compute runtimes create, stop, delete, and watch sandbox workloads for the +Compute runtimes create, suspend, resume, delete, and watch sandbox workloads for the gateway. They do not replace sandbox policy enforcement. Every runtime starts a workload that runs the `openshell-sandbox` supervisor, and the supervisor enforces the sandbox contract locally. @@ -84,19 +84,42 @@ The gateway records driver identity and version from the startup capability response. Elevated gateway info reports that initialized driver snapshot instead of re-querying drivers on each request. +## Suspend and Resume Lifecycle + +The gateway persists lifecycle intent before mutating compute: + +```text +Ready -> Suspending -> Suspended -> Resuming -> Ready +``` + +`StopSandbox` and `ResumeSandbox` are idempotent driver operations. Suspension +retains the driver resource and its persistent workspace boundary while making +exec, SSH, forwarding, and exposed services unavailable. Resume reactivates the +same resource. The gateway requires a fresh supervisor session before a +resuming sandbox returns to `Ready`; stale driver snapshots and supervisor +sessions cannot promote a `Suspended` row. + +Persisted `Suspending` and `Resuming` rows are retried at startup. Stable +`Suspended` rows remain stopped. Docker and Podman retain the stopped container +and attached storage, Kubernetes retains the Sandbox CR and PVC while scaling +compute to zero, and VM retains its launch request and writable overlay beside +a suspension marker. Delete remains a separate operation that removes these +resources. + ## Deletion Lifecycle -Delete requests use per-sandbox gates to serialize delete attempts. A request +Lifecycle requests use per-sandbox gates to serialize suspend, resume, and +delete attempts. A delete request resolves the name once and remains bound to that stable ID. The only -combined lock order is delete gate, then the gateway-wide state guard; external +combined lock order is lifecycle gate, then the gateway-wide state guard; external driver calls run without the global guard. -Delete gates are process-local and do not coordinate gateway replicas. They +Lifecycle gates are process-local and do not coordinate gateway replicas. They serialize attempts rather than share results: if one attempt fails and recovery restores a deletable state, a request waiting on the gate may retry the driver. Persisted resource-version checks remain the cross-replica safety boundary. -Watcher events do not acquire delete gates. Exact resource-version checks allow +Watcher events do not acquire lifecycle gates. Exact resource-version checks allow them to interleave safely: status snapshots are no-ops for `Deleting` rows, deleted events are idempotent, and snapshots for absent rows are ignored. diff --git a/crates/openshell-cli/src/commands/common.rs b/crates/openshell-cli/src/commands/common.rs index e6edb4d33a..45554417bc 100644 --- a/crates/openshell-cli/src/commands/common.rs +++ b/crates/openshell-cli/src/commands/common.rs @@ -59,6 +59,9 @@ pub fn phase_name(phase: i32) -> &'static str { Ok(SandboxPhase::Ready) => "Ready", Ok(SandboxPhase::Error) => "Error", Ok(SandboxPhase::Deleting) => "Deleting", + Ok(SandboxPhase::Suspending) => "Suspending", + Ok(SandboxPhase::Suspended) => "Suspended", + Ok(SandboxPhase::Resuming) => "Resuming", Ok(SandboxPhase::Unknown) | Err(_) => "Unknown", } } diff --git a/crates/openshell-cli/src/main.rs b/crates/openshell-cli/src/main.rs index 4ea2765d25..5058ccec00 100644 --- a/crates/openshell-cli/src/main.rs +++ b/crates/openshell-cli/src/main.rs @@ -1520,6 +1520,22 @@ enum SandboxCommands { all: bool, }, + /// Suspend a sandbox while preserving its workspace. + #[command(help_template = LEAF_HELP_TEMPLATE, next_help_heading = "FLAGS")] + Suspend { + /// Sandbox name (defaults to last-used sandbox). + #[arg(add = ArgValueCompleter::new(completers::complete_sandbox_names))] + name: Option, + }, + + /// Resume a suspended sandbox. + #[command(help_template = LEAF_HELP_TEMPLATE, next_help_heading = "FLAGS")] + Resume { + /// Sandbox name (defaults to last-used sandbox). + #[arg(add = ArgValueCompleter::new(completers::complete_sandbox_names))] + name: Option, + }, + /// Execute a command in a running sandbox. /// /// Runs a command inside an existing sandbox using the gRPC exec endpoint. @@ -3132,6 +3148,14 @@ async fn main() -> Result<()> { ) .await?; } + SandboxCommands::Suspend { name } => { + let name = resolve_sandbox_name(name, &ctx.name, &cli.workspace)?; + run::sandbox_suspend(endpoint, &name, &cli.workspace, &tls).await?; + } + SandboxCommands::Resume { name } => { + let name = resolve_sandbox_name(name, &ctx.name, &cli.workspace)?; + run::sandbox_resume(endpoint, &name, &cli.workspace, &tls).await?; + } SandboxCommands::Connect { name, editor } => { let name = resolve_sandbox_name(name, &ctx.name, &cli.workspace)?; if let Some(editor) = editor.map(Into::into) { @@ -4432,6 +4456,27 @@ mod tests { )); } + #[test] + fn sandbox_suspend_and_resume_accept_optional_names() { + let suspend = Cli::try_parse_from(["openshell", "sandbox", "suspend", "demo"]) + .expect("suspend command should parse"); + assert!(matches!( + suspend.command, + Some(Commands::Sandbox { + command: Some(SandboxCommands::Suspend { name: Some(ref name) }), + }) if name == "demo" + )); + + let resume = Cli::try_parse_from(["openshell", "sandbox", "resume"]) + .expect("resume command should parse"); + assert!(matches!( + resume.command, + Some(Commands::Sandbox { + command: Some(SandboxCommands::Resume { name: None }), + }) + )); + } + #[test] fn sandbox_list_accepts_output_json() { let cli = Cli::try_parse_from(["openshell", "sandbox", "list", "-o", "json"]) diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index 48bf2d3dd5..f76022037c 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -48,10 +48,10 @@ use openshell_core::proto::{ ListSandboxPoliciesRequest, ListSandboxProvidersRequest, ListSandboxesRequest, ListServicesRequest, PolicySource, PolicyStatus, Provider, ProviderCredentialRefreshStatus, ProviderCredentialRefreshStrategy, ProviderProfile, ProviderProfileDiagnostic, - ProviderProfileImportItem, RejectDraftChunkRequest, ResourceRequirements, + ProviderProfileImportItem, RejectDraftChunkRequest, ResourceRequirements, ResumeSandboxRequest, RevokeSshSessionRequest, RotateProviderCredentialRequest, Sandbox, SandboxPhase, SandboxPolicy, SandboxSpec, SandboxTemplate, ServiceEndpointResponse, SetInferenceRouteRequest, SettingScope, - TcpForwardFrame, TcpForwardInit, TcpRelayTarget, UpdateConfigRequest, + SuspendSandboxRequest, TcpForwardFrame, TcpForwardInit, TcpRelayTarget, UpdateConfigRequest, UpdateProviderProfilesRequest, UpdateProviderRequest, WatchSandboxRequest, exec_sandbox_event, setting_value, tcp_forward_init, }; @@ -2419,6 +2419,135 @@ pub async fn sandbox_delete( Ok(()) } +/// Suspend a sandbox while retaining its persistent workspace. +pub async fn sandbox_suspend( + server: &str, + name: &str, + workspace: &str, + tls: &TlsOptions, +) -> Result<()> { + if let Ok(stopped) = stop_forwards_for_sandbox(name) { + for port in stopped { + eprintln!( + "{} Stopped forward of port {port} for sandbox {name}", + "✓".green().bold(), + ); + } + } + + let mut client = grpc_client(server, tls).await?; + let sandbox = client + .suspend_sandbox(SuspendSandboxRequest { + name: name.to_string(), + workspace: workspace.to_string(), + }) + .await + .into_diagnostic()? + .into_inner() + .sandbox + .ok_or_else(|| miette!("gateway returned no sandbox after suspend"))?; + wait_for_lifecycle_phase(&mut client, sandbox, SandboxPhase::Suspended).await?; + println!("{} Suspended sandbox {name}", "✓".green().bold()); + Ok(()) +} + +/// Resume a suspended sandbox and wait until it is ready. +pub async fn sandbox_resume( + server: &str, + name: &str, + workspace: &str, + tls: &TlsOptions, +) -> Result<()> { + let mut client = grpc_client(server, tls).await?; + let sandbox = client + .resume_sandbox(ResumeSandboxRequest { + name: name.to_string(), + workspace: workspace.to_string(), + }) + .await + .into_diagnostic()? + .into_inner() + .sandbox + .ok_or_else(|| miette!("gateway returned no sandbox after resume"))?; + wait_for_lifecycle_phase(&mut client, sandbox, SandboxPhase::Ready).await?; + println!("{} Resumed sandbox {name}", "✓".green().bold()); + Ok(()) +} + +async fn wait_for_lifecycle_phase( + client: &mut crate::tls::GrpcClient, + sandbox: Sandbox, + target: SandboxPhase, +) -> Result { + let current = SandboxPhase::try_from(sandbox.phase()).unwrap_or(SandboxPhase::Unknown); + if current == target { + return Ok(sandbox); + } + if current == SandboxPhase::Error { + return Err(miette!( + "sandbox entered Error while waiting for {target:?}" + )); + } + + let timeout = Duration::from_secs( + std::env::var("OPENSHELL_LIFECYCLE_TIMEOUT") + .ok() + .and_then(|value| value.parse().ok()) + .unwrap_or(300), + ); + let sandbox_id = sandbox.object_id().to_string(); + let mut stream = client + .watch_sandbox(WatchSandboxRequest { + id: sandbox_id, + follow_status: true, + follow_logs: false, + follow_events: false, + log_tail_lines: 0, + event_tail: 0, + stop_on_terminal: false, + log_since_ms: 0, + log_sources: Vec::new(), + log_min_level: String::new(), + }) + .await + .into_diagnostic()? + .into_inner(); + + let deadline = Instant::now() + timeout; + loop { + let remaining = deadline.saturating_duration_since(Instant::now()); + if remaining.is_zero() { + return Err(miette!( + "timed out after {}s waiting for sandbox to reach {target:?}", + timeout.as_secs() + )); + } + let event = tokio::time::timeout(remaining, stream.next()) + .await + .map_err(|_| { + miette!( + "timed out after {}s waiting for sandbox to reach {target:?}", + timeout.as_secs() + ) + })? + .ok_or_else(|| miette!("sandbox watch ended before reaching {target:?}"))? + .into_diagnostic()?; + if let Some(openshell_core::proto::sandbox_stream_event::Payload::Sandbox(sandbox)) = + event.payload + { + let phase = SandboxPhase::try_from(sandbox.phase()).unwrap_or(SandboxPhase::Unknown); + if phase == target { + return Ok(sandbox); + } + if phase == SandboxPhase::Error { + let detail = ready_false_condition_message(sandbox.status.as_ref()) + .unwrap_or_else(|| "sandbox entered Error".to_string()); + return Err(miette!(detail)); + } + } + } +} + /// Return the provider type inferred from the trailing command, if any. fn inferred_provider_type(command: &[String]) -> Option { detect_provider_from_command(command).map(str::to_string) diff --git a/crates/openshell-cli/tests/ensure_providers_integration.rs b/crates/openshell-cli/tests/ensure_providers_integration.rs index 5bd64c2f36..5b9fc87ab0 100644 --- a/crates/openshell-cli/tests/ensure_providers_integration.rs +++ b/crates/openshell-cli/tests/ensure_providers_integration.rs @@ -111,6 +111,20 @@ impl OpenShell for TestOpenShell { Ok(Response::new(SandboxResponse::default())) } + async fn suspend_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + + async fn resume_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + async fn get_sandbox( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/mtls_integration.rs b/crates/openshell-cli/tests/mtls_integration.rs index 38c68ed83a..8569fd4cc2 100644 --- a/crates/openshell-cli/tests/mtls_integration.rs +++ b/crates/openshell-cli/tests/mtls_integration.rs @@ -66,6 +66,20 @@ impl OpenShell for TestOpenShell { )) } + async fn suspend_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + + async fn resume_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + async fn get_sandbox( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/provider_commands_integration.rs b/crates/openshell-cli/tests/provider_commands_integration.rs index 24645ea259..26ff7b2f62 100644 --- a/crates/openshell-cli/tests/provider_commands_integration.rs +++ b/crates/openshell-cli/tests/provider_commands_integration.rs @@ -129,6 +129,20 @@ impl OpenShell for TestOpenShell { Ok(Response::new(SandboxResponse::default())) } + async fn suspend_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + + async fn resume_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + async fn get_sandbox( &self, request: tonic::Request, diff --git a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs index 8bacb76a2d..0314ee4417 100644 --- a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs +++ b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs @@ -114,6 +114,20 @@ impl OpenShell for TestOpenShell { })) } + async fn suspend_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + + async fn resume_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + async fn get_sandbox( &self, request: tonic::Request, diff --git a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs index 019b2b12e4..23ad7ff258 100644 --- a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs +++ b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs @@ -79,6 +79,20 @@ impl OpenShell for TestOpenShell { Ok(Response::new(SandboxResponse::default())) } + async fn suspend_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + + async fn resume_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + async fn get_sandbox( &self, request: tonic::Request, diff --git a/crates/openshell-core/src/error.rs b/crates/openshell-core/src/error.rs index a149cf006a..8c23e30198 100644 --- a/crates/openshell-core/src/error.rs +++ b/crates/openshell-core/src/error.rs @@ -113,6 +113,9 @@ pub enum ComputeDriverError { /// The requested sandbox already exists. #[error("sandbox already exists")] AlreadyExists, + /// The requested sandbox does not exist. + #[error("sandbox not found")] + NotFound, /// The request contains an invalid argument. #[error("{0}")] InvalidArgument(String), @@ -128,6 +131,7 @@ impl From for tonic::Status { fn from(err: ComputeDriverError) -> Self { match err { ComputeDriverError::AlreadyExists => Self::already_exists("sandbox already exists"), + ComputeDriverError::NotFound => Self::not_found("sandbox not found"), ComputeDriverError::InvalidArgument(m) => Self::invalid_argument(m), ComputeDriverError::Precondition(m) => Self::failed_precondition(m), ComputeDriverError::Message(m) => Self::internal(m), diff --git a/crates/openshell-core/src/telemetry.rs b/crates/openshell-core/src/telemetry.rs index 49ce620f4f..f7a1cdfd1e 100644 --- a/crates/openshell-core/src/telemetry.rs +++ b/crates/openshell-core/src/telemetry.rs @@ -103,6 +103,8 @@ impl LifecycleResource { pub enum LifecycleOperation { Create, Delete, + Suspend, + Resume, Update, } @@ -112,6 +114,8 @@ impl LifecycleOperation { match self { Self::Create => "create", Self::Delete => "delete", + Self::Suspend => "suspend", + Self::Resume => "resume", Self::Update => "update", } } diff --git a/crates/openshell-driver-docker/README.md b/crates/openshell-driver-docker/README.md index 05faf53c5c..0dd4320bdf 100644 --- a/crates/openshell-driver-docker/README.md +++ b/crates/openshell-driver-docker/README.md @@ -18,6 +18,15 @@ The gateway runs as a host process. The Docker driver creates one container per sandbox and starts the `openshell-sandbox` supervisor inside that container. The supervisor then creates the nested sandbox namespace for the agent process. +## Suspend and Resume + +Suspend stops the managed container without removing it. Docker retains the +container writable layer, attached volumes, labels, token material, and restart +policy. Resume starts that same container, so files in the resolved OCI +workspace remain available. A durably suspended sandbox is excluded from +gateway startup recovery and stays stopped across gateway restarts. Delete +continues to force-remove the container and clean up driver-owned material. + Before creating the container, the driver inspects the final sandbox image and captures its immutable image ID, raw OCI `Config.User`, and OCI `Config.WorkingDir`. Container creation uses that image ID, preventing a diff --git a/crates/openshell-driver-docker/src/lib.rs b/crates/openshell-driver-docker/src/lib.rs index dd4d9ef0f0..3eb6d33151 100644 --- a/crates/openshell-driver-docker/src/lib.rs +++ b/crates/openshell-driver-docker/src/lib.rs @@ -42,11 +42,12 @@ use openshell_core::proto::compute::v1::{ DriverSandboxTemplate, GatewayListenerRequirement, GetCapabilitiesRequest, GetCapabilitiesResponse, GetGatewayListenerRequirementsRequest, GetGatewayListenerRequirementsResponse, GetSandboxRequest, GetSandboxResponse, - GpuResourceRequirements, ListSandboxesRequest, ListSandboxesResponse, StopSandboxRequest, - StopSandboxResponse, ValidateSandboxCreateRequest, ValidateSandboxCreateResponse, - WatchSandboxesDeletedEvent, WatchSandboxesEvent, WatchSandboxesPlatformEvent, - WatchSandboxesRequest, WatchSandboxesSandboxEvent, compute_driver_server::ComputeDriver, - gateway_listener_requirement::Selector, watch_sandboxes_event, + GpuResourceRequirements, ListSandboxesRequest, ListSandboxesResponse, ResumeSandboxRequest, + ResumeSandboxResponse, StopSandboxRequest, StopSandboxResponse, ValidateSandboxCreateRequest, + ValidateSandboxCreateResponse, WatchSandboxesDeletedEvent, WatchSandboxesEvent, + WatchSandboxesPlatformEvent, WatchSandboxesRequest, WatchSandboxesSandboxEvent, + compute_driver_server::ComputeDriver, gateway_listener_requirement::Selector, + watch_sandboxes_event, }; use openshell_core::proto_struct::{ deserialize_optional_non_empty_string_list, struct_to_json_value, @@ -1479,9 +1480,25 @@ impl ComputeDriver for DockerComputeDriver { self.stop_sandbox_inner(&request.sandbox_id, &request.sandbox_name) .await?; + self.publish_container_snapshot(&request.sandbox_id, &request.sandbox_name) + .await?; Ok(Response::new(StopSandboxResponse {})) } + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + require_sandbox_identifier(&request.sandbox_id, &request.sandbox_name)?; + if !Self::resume_sandbox(self, &request.sandbox_id, &request.sandbox_name).await? { + return Err(Status::not_found("sandbox not found")); + } + self.publish_container_snapshot(&request.sandbox_id, &request.sandbox_name) + .await?; + Ok(Response::new(ResumeSandboxResponse {})) + } + async fn delete_sandbox( &self, request: Request, diff --git a/crates/openshell-driver-kubernetes/README.md b/crates/openshell-driver-kubernetes/README.md index 1356e2d932..78b99eb0cb 100644 --- a/crates/openshell-driver-kubernetes/README.md +++ b/crates/openshell-driver-kubernetes/README.md @@ -36,6 +36,13 @@ This is a stopgap persistence model. It preserves user files across pod rescheduling but duplicates the base workspace and does not automatically apply image updates to existing PVCs. Future snapshotting should replace it. +Suspend preserves the Agent Sandbox resource and workspace PVC while stopping +its pod. The driver sets `spec.operatingMode: Suspended` for `v1beta1` or +`spec.replicas: 0` for `v1alpha1`. Resume sets `Running` or one replica for the +same resource, so the replacement pod mounts the existing claim. Delete is the +only lifecycle operation that removes the Sandbox resource and its owned +storage. + The workspace PVC size defaults to `workspace_default_storage_size`. Set `workspace_storage_class` to pin the PVC to a specific `StorageClass`; an empty value omits `storageClassName` so the cluster's default `StorageClass` applies. diff --git a/crates/openshell-driver-kubernetes/src/driver.rs b/crates/openshell-driver-kubernetes/src/driver.rs index 2f1ea72a32..722943e154 100644 --- a/crates/openshell-driver-kubernetes/src/driver.rs +++ b/crates/openshell-driver-kubernetes/src/driver.rs @@ -13,7 +13,9 @@ use futures::{Stream, StreamExt, TryStreamExt}; use k8s_openapi::api::core::v1::{ Event as KubeEventObj, Namespace, Node, PersistentVolumeClaimVolumeSource, Volume, VolumeMount, }; -use kube::api::{Api, ApiResource, DeleteParams, ListParams, PostParams, Preconditions}; +use kube::api::{ + Api, ApiResource, DeleteParams, ListParams, Patch, PatchParams, PostParams, Preconditions, +}; use kube::core::gvk::GroupVersionKind; use kube::core::{DynamicObject, ObjectMeta}; use kube::runtime::watcher::{self, Event}; @@ -927,6 +929,102 @@ impl KubernetesComputeDriver { } } + pub async fn stop_sandbox(&self, sandbox_id: &str) -> Result<(), String> { + let (agent_sandbox_api, kube_name) = self + .patch_sandbox_operating_state(sandbox_id, false) + .await?; + + let deadline = tokio::time::Instant::now() + KUBE_API_TIMEOUT; + loop { + let object = agent_sandbox_api + .api + .get(&kube_name) + .await + .map_err(|err| err.to_string())?; + if kubernetes_sandbox_is_suspended(&object) { + return Ok(()); + } + if tokio::time::Instant::now() >= deadline { + return Err(format!( + "timed out after {}s waiting for Kubernetes sandbox to suspend", + KUBE_API_TIMEOUT.as_secs() + )); + } + tokio::time::sleep(Duration::from_millis(250)).await; + } + } + + pub async fn resume_sandbox(&self, sandbox_id: &str) -> Result<(), String> { + self.patch_sandbox_operating_state(sandbox_id, true) + .await + .map(|_| ()) + } + + async fn patch_sandbox_operating_state( + &self, + sandbox_id: &str, + running: bool, + ) -> Result<(AgentSandboxApi, String), String> { + let agent_sandbox_api = self + .supported_agent_sandbox_api(self.client.clone()) + .await?; + let selector = + format!("{LABEL_MANAGED_BY}={LABEL_MANAGED_BY_VALUE},{LABEL_SANDBOX_ID}={sandbox_id}"); + let list = tokio::time::timeout( + KUBE_API_TIMEOUT, + agent_sandbox_api + .api + .list(&ListParams::default().labels(&selector)), + ) + .await + .map_err(|_| { + format!( + "timed out after {}s waiting for Kubernetes API", + KUBE_API_TIMEOUT.as_secs() + ) + })? + .map_err(|err| err.to_string())?; + let object = list + .items + .into_iter() + .next() + .ok_or_else(|| "sandbox not found".to_string())?; + let kube_name = object + .metadata + .name + .ok_or_else(|| "sandbox resource has no name".to_string())?; + let resource_version = object.metadata.resource_version.unwrap_or_default(); + let desired = sandbox_operating_state_patch( + &agent_sandbox_api.resource.version, + &resource_version, + running, + ); + tokio::time::timeout( + KUBE_API_TIMEOUT, + agent_sandbox_api.api.patch( + &kube_name, + &PatchParams::default(), + &Patch::Merge(&desired), + ), + ) + .await + .map_err(|_| { + format!( + "timed out after {}s waiting for Kubernetes API", + KUBE_API_TIMEOUT.as_secs() + ) + })? + .map_err(|err| err.to_string())?; + + info!( + sandbox_id, + sandbox_api_version = %agent_sandbox_api.resource.version, + running, + "Updated Kubernetes sandbox operating state" + ); + Ok((agent_sandbox_api, kube_name)) + } + pub async fn delete_sandbox(&self, sandbox_id: &str) -> Result { info!( sandbox_id = %sandbox_id, @@ -3121,6 +3219,46 @@ fn status_from_object(obj: &DynamicObject) -> Option { }) } +fn kubernetes_sandbox_is_suspended(obj: &DynamicObject) -> bool { + obj.data + .get("status") + .and_then(|status| status.get("conditions")) + .and_then(serde_json::Value::as_array) + .is_some_and(|conditions| { + conditions.iter().any(|condition| { + condition.get("type").and_then(serde_json::Value::as_str) == Some("Suspended") + && condition + .get("status") + .and_then(serde_json::Value::as_str) + .is_some_and(|status| status.eq_ignore_ascii_case("true")) + }) + }) + || obj + .data + .get("status") + .and_then(|status| status.get("replicas")) + .and_then(serde_json::Value::as_i64) + == Some(0) +} + +fn sandbox_operating_state_patch( + api_version: &str, + resource_version: &str, + running: bool, +) -> serde_json::Value { + if api_version == SANDBOX_VERSION_V1BETA1 { + serde_json::json!({ + "metadata": {"resourceVersion": resource_version}, + "spec": {"operatingMode": if running { "Running" } else { "Suspended" }} + }) + } else { + serde_json::json!({ + "metadata": {"resourceVersion": resource_version}, + "spec": {"replicas": i32::from(running)} + }) + } +} + fn condition_from_value(value: &serde_json::Value) -> Option { let obj = value.as_object()?; Some(SandboxCondition { @@ -3194,6 +3332,19 @@ mod tests { assert!(should_try_next_sandbox_api_version(&raw)); } + #[test] + fn lifecycle_patch_uses_version_specific_operating_state() { + let beta_suspend = sandbox_operating_state_patch(SANDBOX_VERSION_V1BETA1, "42", false); + assert_eq!(beta_suspend["metadata"]["resourceVersion"], "42"); + assert_eq!(beta_suspend["spec"]["operatingMode"], "Suspended"); + assert!(beta_suspend["spec"].get("replicas").is_none()); + + let alpha_resume = sandbox_operating_state_patch(SANDBOX_VERSION_V1ALPHA1, "43", true); + assert_eq!(alpha_resume["metadata"]["resourceVersion"], "43"); + assert_eq!(alpha_resume["spec"]["replicas"], 1); + assert!(alpha_resume["spec"].get("operatingMode").is_none()); + } + #[test] fn sandbox_api_version_probe_keeps_non_404_errors() { let err = kube_api_error(403, "sandboxes.agents.x-k8s.io is forbidden"); diff --git a/crates/openshell-driver-kubernetes/src/grpc.rs b/crates/openshell-driver-kubernetes/src/grpc.rs index 6eeb51cd73..e3b81d27fd 100644 --- a/crates/openshell-driver-kubernetes/src/grpc.rs +++ b/crates/openshell-driver-kubernetes/src/grpc.rs @@ -8,9 +8,10 @@ use openshell_core::proto::compute::v1::{ CreateSandboxRequest, CreateSandboxResponse, DeleteSandboxRequest, DeleteSandboxResponse, GetCapabilitiesRequest, GetCapabilitiesResponse, GetGatewayListenerRequirementsRequest, GetGatewayListenerRequirementsResponse, GetSandboxRequest, GetSandboxResponse, - ListSandboxesRequest, ListSandboxesResponse, StopSandboxRequest, StopSandboxResponse, - ValidateSandboxCreateRequest, ValidateSandboxCreateResponse, WatchSandboxesEvent, - WatchSandboxesRequest, compute_driver_server::ComputeDriver, + ListSandboxesRequest, ListSandboxesResponse, ResumeSandboxRequest, ResumeSandboxResponse, + StopSandboxRequest, StopSandboxResponse, ValidateSandboxCreateRequest, + ValidateSandboxCreateResponse, WatchSandboxesEvent, WatchSandboxesRequest, + compute_driver_server::ComputeDriver, }; use std::pin::Pin; use tonic::{Request, Response, Status}; @@ -112,11 +113,32 @@ impl ComputeDriver for ComputeDriverService { async fn stop_sandbox( &self, - _request: Request, + request: Request, ) -> Result, Status> { - Err(Status::unimplemented( - "stop sandbox is not implemented by the kubernetes compute driver", - )) + let request = request.into_inner(); + if request.sandbox_id.is_empty() { + return Err(Status::invalid_argument("sandbox_id is required")); + } + self.driver + .stop_sandbox(&request.sandbox_id) + .await + .map_err(kubernetes_lifecycle_status)?; + Ok(Response::new(StopSandboxResponse {})) + } + + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + if request.sandbox_id.is_empty() { + return Err(Status::invalid_argument("sandbox_id is required")); + } + self.driver + .resume_sandbox(&request.sandbox_id) + .await + .map_err(kubernetes_lifecycle_status)?; + Ok(Response::new(ResumeSandboxResponse {})) } async fn delete_sandbox( @@ -152,6 +174,14 @@ impl ComputeDriver for ComputeDriverService { } } +fn kubernetes_lifecycle_status(message: String) -> Status { + if message == "sandbox not found" { + Status::not_found(message) + } else { + Status::internal(message) + } +} + #[cfg(test)] mod tests { use crate::KubernetesDriverError; diff --git a/crates/openshell-driver-podman/README.md b/crates/openshell-driver-podman/README.md index 965a295d19..3129b84be2 100644 --- a/crates/openshell-driver-podman/README.md +++ b/crates/openshell-driver-podman/README.md @@ -19,6 +19,15 @@ independently. For a rootless networking deep dive, see [NETWORKING.md](NETWORKING.md). +## Suspend and Resume + +Suspend stops the managed container without deleting it. The per-sandbox named +workspace volume, token and proxy-auth secrets, labels, and container metadata +remain intact. Resume starts the same container and reuses the same named +volume. Stopped managed containers remain visible through list and watch +reconciliation. Delete remains responsible for removing the container, +driver-owned secrets, and workspace volume. + ## Architecture The Podman driver communicates with the Podman daemon over a Unix socket and diff --git a/crates/openshell-driver-podman/src/driver.rs b/crates/openshell-driver-podman/src/driver.rs index 51c689fb29..26f9b2f1a3 100644 --- a/crates/openshell-driver-podman/src/driver.rs +++ b/crates/openshell-driver-podman/src/driver.rs @@ -3,7 +3,7 @@ //! Podman compute driver. -use crate::client::{PodmanApiError, PodmanClient, VolumeInspect}; +use crate::client::{ContainerListEntry, PodmanApiError, PodmanClient, VolumeInspect}; use crate::config::PodmanComputeConfig; use crate::container::{self, LABEL_MANAGED_FILTER, LABEL_SANDBOX_ID, PodmanSandboxDriverConfig}; use crate::watcher::{ @@ -36,7 +36,7 @@ impl From for ComputeDriverError { fn from(value: PodmanApiError) -> Self { match value { PodmanApiError::Conflict(_) => Self::AlreadyExists, - PodmanApiError::NotFound(msg) => Self::Message(format!("not found: {msg}")), + PodmanApiError::NotFound(_) => Self::NotFound, other => Self::Message(other.to_string()), } } @@ -815,20 +815,32 @@ impl PodmanComputeDriver { &self, sandbox_id: &str, ) -> Result, ComputeDriverError> { + Ok(self.find_container(sandbox_id).await?.map(|entry| entry.id)) + } + + async fn find_container( + &self, + sandbox_id: &str, + ) -> Result, ComputeDriverError> { let id_filter = format!("{LABEL_SANDBOX_ID}={sandbox_id}"); let entries = self .client .list_containers(&[LABEL_MANAGED_FILTER, &id_filter]) .await .map_err(ComputeDriverError::from)?; - Ok(entries.first().map(|e| e.id.clone())) + Ok(entries.into_iter().next()) } /// Stop a sandbox container without deleting it. pub async fn stop_sandbox(&self, sandbox_id: &str) -> Result<(), ComputeDriverError> { - let container_id = self.find_container_id(sandbox_id).await?.ok_or_else(|| { - ComputeDriverError::Precondition("sandbox container not found".into()) - })?; + let container = self + .find_container(sandbox_id) + .await? + .ok_or(ComputeDriverError::NotFound)?; + if container.state != "running" { + return Ok(()); + } + let container_id = container.id; info!(sandbox_id = %sandbox_id, container = %container_id, "Stopping sandbox container"); self.client @@ -837,6 +849,24 @@ impl PodmanComputeDriver { .map_err(ComputeDriverError::from) } + /// Resume a previously stopped sandbox container. + pub async fn resume_sandbox(&self, sandbox_id: &str) -> Result<(), ComputeDriverError> { + let container = self + .find_container(sandbox_id) + .await? + .ok_or(ComputeDriverError::NotFound)?; + if container.state == "running" { + return Ok(()); + } + let container_id = container.id; + info!(sandbox_id = %sandbox_id, container = %container_id, "Resuming sandbox container"); + + self.client + .start_container(&container_id) + .await + .map_err(ComputeDriverError::from) + } + /// Delete a sandbox container and its workspace volume. pub async fn delete_sandbox(&self, sandbox_id: &str) -> Result { if sandbox_id.is_empty() { @@ -1172,7 +1202,54 @@ mod tests { #[test] fn podman_driver_error_from_not_found() { let err = ComputeDriverError::from(PodmanApiError::NotFound("gone".into())); - assert!(matches!(err, ComputeDriverError::Message(_))); + assert!(matches!(err, ComputeDriverError::NotFound)); + } + + #[tokio::test] + async fn stop_and_resume_target_the_existing_container() { + let (stop_socket, stop_requests, stop_handle) = spawn_podman_stub( + "lifecycle-stop", + vec![ + StubResponse::new(StatusCode::OK, r#"[{"Id":"ctr-1","State":"running"}]"#), + StubResponse::new(StatusCode::NO_CONTENT, ""), + ], + ); + test_driver(stop_socket.clone()) + .stop_sandbox("sandbox-1") + .await + .expect("stop should succeed"); + stop_handle.await.expect("stop stub should finish"); + assert_eq!( + stop_requests + .lock() + .expect("request log lock should not be poisoned")[1], + format!( + "POST {}", + api_path("/libpod/containers/ctr-1/stop?timeout=10") + ) + ); + + let (start_socket, start_requests, start_handle) = spawn_podman_stub( + "lifecycle-start", + vec![ + StubResponse::new(StatusCode::OK, r#"[{"Id":"ctr-1","State":"stopped"}]"#), + StubResponse::new(StatusCode::NO_CONTENT, ""), + ], + ); + test_driver(start_socket.clone()) + .resume_sandbox("sandbox-1") + .await + .expect("resume should succeed"); + start_handle.await.expect("start stub should finish"); + assert_eq!( + start_requests + .lock() + .expect("request log lock should not be poisoned")[1], + format!("POST {}", api_path("/libpod/containers/ctr-1/start")) + ); + + let _ = fs::remove_file(stop_socket); + let _ = fs::remove_file(start_socket); } #[test] diff --git a/crates/openshell-driver-podman/src/grpc.rs b/crates/openshell-driver-podman/src/grpc.rs index 2d0792d447..ea5d54ac28 100644 --- a/crates/openshell-driver-podman/src/grpc.rs +++ b/crates/openshell-driver-podman/src/grpc.rs @@ -8,9 +8,10 @@ use openshell_core::proto::compute::v1::{ CreateSandboxRequest, CreateSandboxResponse, DeleteSandboxRequest, DeleteSandboxResponse, GetCapabilitiesRequest, GetCapabilitiesResponse, GetGatewayListenerRequirementsRequest, GetGatewayListenerRequirementsResponse, GetSandboxRequest, GetSandboxResponse, - ListSandboxesRequest, ListSandboxesResponse, StopSandboxRequest, StopSandboxResponse, - ValidateSandboxCreateRequest, ValidateSandboxCreateResponse, WatchSandboxesEvent, - WatchSandboxesRequest, compute_driver_server::ComputeDriver, + ListSandboxesRequest, ListSandboxesResponse, ResumeSandboxRequest, ResumeSandboxResponse, + StopSandboxRequest, StopSandboxResponse, ValidateSandboxCreateRequest, + ValidateSandboxCreateResponse, WatchSandboxesEvent, WatchSandboxesRequest, + compute_driver_server::ComputeDriver, }; use std::pin::Pin; use tonic::{Request, Response, Status}; @@ -127,6 +128,21 @@ impl ComputeDriver for ComputeDriverService { Ok(Response::new(StopSandboxResponse {})) } + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + if request.sandbox_id.is_empty() { + return Err(Status::invalid_argument("sandbox_id is required")); + } + self.driver + .resume_sandbox(&request.sandbox_id) + .await + .map_err(Status::from)?; + Ok(Response::new(ResumeSandboxResponse {})) + } + async fn delete_sandbox( &self, request: Request, @@ -181,6 +197,12 @@ mod tests { assert_eq!(status.code(), tonic::Code::AlreadyExists); } + #[test] + fn not_found_driver_errors_map_to_not_found_status() { + let status: Status = ComputeDriverError::NotFound.into(); + assert_eq!(status.code(), tonic::Code::NotFound); + } + fn test_service(socket_path: PathBuf) -> ComputeDriverService { let config = PodmanComputeConfig { socket_path: Some(socket_path), diff --git a/crates/openshell-driver-vm/README.md b/crates/openshell-driver-vm/README.md index 23f75227a7..a26e049c07 100644 --- a/crates/openshell-driver-vm/README.md +++ b/crates/openshell-driver-vm/README.md @@ -199,6 +199,13 @@ restarts each persisted VM launcher, and preserves any existing `overlay.ext4` instead of cloning a fresh overlay template. If a restart happened before the overlay was created, the driver creates it during the resume attempt. +Suspension writes a marker in the sandbox state directory before terminating +the launcher and releasing host GPU and network allocations. It retains +`sandbox.pb`, `overlay.ext4`, and lifecycle-extension state. Startup registers +marked sandboxes without launching compute. Resume removes the marker and uses +the normal persisted restore path with the existing overlay. Delete removes the +entire sandbox state directory, including a suspended marker and overlay. + ## Logs and debugging Raise log verbosity for both processes: diff --git a/crates/openshell-driver-vm/src/driver.rs b/crates/openshell-driver-vm/src/driver.rs index 9b6c0dd6ce..f9f8ef95bb 100644 --- a/crates/openshell-driver-vm/src/driver.rs +++ b/crates/openshell-driver-vm/src/driver.rs @@ -43,10 +43,10 @@ use openshell_core::proto::compute::v1::{ DriverSandboxTemplate as SandboxTemplate, GetCapabilitiesRequest, GetCapabilitiesResponse, GetGatewayListenerRequirementsRequest, GetGatewayListenerRequirementsResponse, GetSandboxRequest, GetSandboxResponse, ListSandboxesRequest, ListSandboxesResponse, - StopSandboxRequest, StopSandboxResponse, ValidateSandboxCreateRequest, - ValidateSandboxCreateResponse, WatchSandboxesDeletedEvent, WatchSandboxesEvent, - WatchSandboxesPlatformEvent, WatchSandboxesRequest, WatchSandboxesSandboxEvent, - compute_driver_server::ComputeDriver, watch_sandboxes_event, + ResumeSandboxRequest, ResumeSandboxResponse, StopSandboxRequest, StopSandboxResponse, + ValidateSandboxCreateRequest, ValidateSandboxCreateResponse, WatchSandboxesDeletedEvent, + WatchSandboxesEvent, WatchSandboxesPlatformEvent, WatchSandboxesRequest, + WatchSandboxesSandboxEvent, compute_driver_server::ComputeDriver, watch_sandboxes_event, }; use openshell_core::proto_struct::{ deserialize_optional_non_empty_string_list, struct_to_json_value, @@ -166,6 +166,7 @@ const OVERLAY_TEMPLATE_CACHE_DIR: &str = "overlay-templates"; const OVERLAY_TEMPLATE_CACHE_LAYOUT_VERSION: &str = "sandbox-overlay-ext4-v1"; const SANDBOX_OVERLAY_IMAGE: &str = "overlay.ext4"; const SANDBOX_REQUEST_FILE: &str = "sandbox.pb"; +const SANDBOX_SUSPENDED_FILE: &str = "suspended"; const GUEST_IMAGE_CONFIG_DIR: &str = "openshell-image"; const GUEST_IMAGE_OCI_LAYOUT_DIR: &str = "oci"; const GUEST_IMAGE_OCI_REF: &str = "openshell"; @@ -1058,6 +1059,134 @@ impl VmDriver { Ok(()) } + pub async fn stop_sandbox(&self, sandbox_id: &str, sandbox_name: &str) -> Result<(), Status> { + if !sandbox_id.is_empty() { + validate_sandbox_id(sandbox_id)?; + } + let record_id = { + let registry = self.registry.lock().await; + if registry.contains_key(sandbox_id) { + Some(sandbox_id.to_string()) + } else { + registry + .iter() + .find(|(_, record)| record.snapshot.name == sandbox_name) + .map(|(id, _)| id.clone()) + } + } + .ok_or_else(|| Status::not_found("sandbox not found"))?; + + let state_dir = { + let registry = self.registry.lock().await; + registry + .get(&record_id) + .ok_or_else(|| Status::not_found("sandbox not found"))? + .state_dir + .clone() + }; + + // Persist intent before detaching process handles or releasing host + // allocations. If this write fails, the live record remains intact. + tokio::fs::write(state_dir.join(SANDBOX_SUSPENDED_FILE), b"suspended\n") + .await + .map_err(|err| Status::internal(format!("persist suspension marker failed: {err}")))?; + + let (process, provisioning_task, has_gpu, has_qemu_network, snapshot) = { + let mut registry = self.registry.lock().await; + let record = registry + .get_mut(&record_id) + .ok_or_else(|| Status::not_found("sandbox not found"))?; + ( + record.process.take(), + record.provisioning_task.take(), + record.gpu_bdf.take().is_some(), + std::mem::take(&mut record.qemu_network_allocated), + record.snapshot.clone(), + ) + }; + + if let Some(task) = provisioning_task { + task.abort(); + } + if let Some(process) = process { + let mut process = process.lock().await; + process.deleting = true; + terminate_vm_process(&mut process.child) + .await + .map_err(|err| Status::internal(format!("failed to stop vm: {err}")))?; + } + self.lifecycle_extensions + .after_launch_failed(&snapshot, &state_dir, LaunchAbortReason::Suspended) + .await; + self.release_allocations(&record_id, has_gpu, has_qemu_network); + + if let Some(snapshot) = self + .set_snapshot_condition(&record_id, suspended_condition(), false) + .await + { + self.publish_snapshot(snapshot); + } + self.publish_platform_event( + record_id, + platform_event( + "vm", + "Normal", + "Suspended", + "VM sandbox suspended".to_string(), + ), + ); + Ok(()) + } + + pub async fn resume_sandbox(&self, sandbox_id: &str, sandbox_name: &str) -> Result<(), Status> { + if !sandbox_id.is_empty() { + validate_sandbox_id(sandbox_id)?; + } + let (record_id, state_dir, already_running) = { + let registry = self.registry.lock().await; + let (id, record) = if let Some(entry) = registry.get_key_value(sandbox_id) { + entry + } else { + registry + .iter() + .find(|(_, record)| record.snapshot.name == sandbox_name) + .ok_or_else(|| Status::not_found("sandbox not found"))? + }; + ( + id.clone(), + record.state_dir.clone(), + record.process.is_some() || record.provisioning_task.is_some(), + ) + }; + if already_running { + return Ok(()); + } + + let sandbox = read_sandbox_request(&state_dir.join(SANDBOX_REQUEST_FILE)) + .await + .map_err(|err| { + Status::internal(format!("read sandbox resume metadata failed: {err}")) + })?; + let suspended_record = self + .registry + .lock() + .await + .remove(&record_id) + .ok_or_else(|| Status::not_found("sandbox not found"))?; + let restored = self + .restore_persisted_sandbox(sandbox, state_dir, true, &tracing::Span::current()) + .await; + if !restored { + self.registry + .lock() + .await + .entry(record_id) + .or_insert(suspended_record); + return Err(Status::internal("failed to resume persisted VM sandbox")); + } + Ok(()) + } + #[tracing::instrument( name = "vm.delete", skip(self), @@ -1264,24 +1393,50 @@ impl VmDriver { continue; } - self.restore_persisted_sandbox(sandbox, state_dir, &tracing::Span::current()) + if tokio::fs::metadata(state_dir.join(SANDBOX_SUSPENDED_FILE)) + .await + .is_ok() + { + let snapshot = sandbox_snapshot(&sandbox, suspended_condition(), false); + let mut registry = self.registry.lock().await; + registry.entry(sandbox.id.clone()).or_insert(SandboxRecord { + snapshot: snapshot.clone(), + state_dir: state_dir.clone(), + process: None, + provisioning_task: None, + gpu_bdf: None, + qemu_network_allocated: false, + deleting: false, + }); + drop(registry); + self.publish_snapshot(snapshot); + info!(sandbox_id = %sandbox.id, "vm driver: restored suspended sandbox without launching compute"); + continue; + } + + self.restore_persisted_sandbox(sandbox, state_dir, false, &tracing::Span::current()) .await; } } + /// Restore a persisted sandbox and report whether the driver accepted it. + /// For explicit resume, the suspension marker is cleared only after all + /// restore preflight checks pass and the replacement registry record is + /// installed. A failed restore therefore remains durably suspended. async fn restore_persisted_sandbox( &self, sandbox: Sandbox, state_dir: PathBuf, + clear_suspension_marker: bool, reconciliation_span: &tracing::Span, - ) { + ) -> bool { let Some(image_ref) = self.resolved_sandbox_image(&sandbox) else { warn!( sandbox_id = %sandbox.id, sandbox_name = %sandbox.name, "vm driver: cannot restore persisted sandbox without image" ); - return; + return false; }; let tls_paths = match self.config.tls_paths() { Ok(paths) => paths, @@ -1292,7 +1447,7 @@ impl VmDriver { error = %err, "vm driver: cannot restore persisted sandbox TLS configuration" ); - return; + return false; } }; @@ -1304,7 +1459,7 @@ impl VmDriver { error = %err.message(), "vm driver: cannot restore persisted sandbox extension state" ); - return; + return false; } let persisted = RestoreContext { @@ -1319,14 +1474,14 @@ impl VmDriver { error = %err, "vm driver: lifecycle extension rejected persisted sandbox restore" ); - return; + return false; } let snapshot = sandbox_snapshot(&sandbox, provisioning_condition(), false); { let mut registry = self.registry.lock().await; if registry.contains_key(&sandbox.id) { - return; + return false; } registry.insert( sandbox.id.clone(), @@ -1342,6 +1497,23 @@ impl VmDriver { ); } + if clear_suspension_marker { + match tokio::fs::remove_file(state_dir.join(SANDBOX_SUSPENDED_FILE)).await { + Ok(()) => {} + Err(err) if err.kind() == std::io::ErrorKind::NotFound => {} + Err(err) => { + self.registry.lock().await.remove(&sandbox.id); + warn!( + sandbox_id = %sandbox.id, + state_dir = %state_dir.display(), + error = %err, + "vm driver: cannot clear suspension marker for persisted sandbox restore" + ); + return false; + } + } + } + self.publish_platform_event( sandbox.id.clone(), platform_event( @@ -1392,6 +1564,7 @@ impl VmDriver { } else { task.abort(); } + true } fn release_gpu(&self, sandbox_id: &str) { @@ -3179,11 +3352,22 @@ impl ComputeDriver for VmDriver { async fn stop_sandbox( &self, - _request: Request, + request: Request, ) -> Result, Status> { - Err(Status::unimplemented( - "stop sandbox is not implemented by the vm compute driver", - )) + let request = request.into_inner(); + self.stop_sandbox(&request.sandbox_id, &request.sandbox_name) + .await?; + Ok(Response::new(StopSandboxResponse {})) + } + + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + self.resume_sandbox(&request.sandbox_id, &request.sandbox_name) + .await?; + Ok(Response::new(ResumeSandboxResponse {})) } async fn delete_sandbox( @@ -5184,6 +5368,16 @@ fn deleting_condition() -> SandboxCondition { } } +fn suspended_condition() -> SandboxCondition { + SandboxCondition { + r#type: "Suspended".to_string(), + status: "True".to_string(), + reason: "ComputeStopped".to_string(), + message: "VM compute is stopped and persistent state is retained".to_string(), + last_transition_time: String::new(), + } +} + fn error_condition(reason: &str, message: &str) -> SandboxCondition { SandboxCondition { r#type: "Ready".to_string(), @@ -6395,6 +6589,62 @@ mod tests { let _ = std::fs::remove_dir_all(base); } + #[tokio::test] + async fn failed_resume_preserves_suspended_state() { + let temp = tempfile::tempdir().unwrap(); + let mut driver = test_driver_with_extensions(LifecycleExtensionRegistry::new()); + driver.config.state_dir = temp.path().to_path_buf(); + let sandbox = Sandbox { + id: "sandbox-suspended".to_string(), + name: "suspended".to_string(), + ..Default::default() + }; + let state_dir = temp.path().join("sandboxes").join(&sandbox.id); + create_private_dir_all(&state_dir).await.unwrap(); + write_sandbox_request(&state_dir, &sandbox).await.unwrap(); + tokio::fs::write(state_dir.join(SANDBOX_SUSPENDED_FILE), b"suspended\n") + .await + .unwrap(); + let snapshot = sandbox_snapshot(&sandbox, suspended_condition(), false); + driver.registry.lock().await.insert( + sandbox.id.clone(), + SandboxRecord { + snapshot, + state_dir: state_dir.clone(), + process: None, + provisioning_task: None, + gpu_bdf: None, + qemu_network_allocated: false, + deleting: false, + }, + ); + + let err = driver + .resume_sandbox(&sandbox.id, &sandbox.name) + .await + .expect_err("resume without an image should fail"); + + assert_eq!(err.code(), Code::Internal); + assert!( + tokio::fs::metadata(state_dir.join(SANDBOX_SUSPENDED_FILE)) + .await + .is_ok(), + "failed resume must retain its durable suspension marker" + ); + let restored = driver + .get_sandbox(&sandbox.id, &sandbox.name) + .await + .unwrap() + .expect("failed resume must retain its suspended registry record"); + let condition = restored + .status + .as_ref() + .and_then(|status| status.conditions.first()) + .expect("suspended condition"); + assert_eq!(condition.r#type, "Suspended"); + assert_eq!(condition.status, "True"); + } + #[test] fn prepare_sandbox_overlay_preserves_existing_overlay_on_resume() { let base = unique_temp_dir(); diff --git a/crates/openshell-driver-vm/src/lifecycle.rs b/crates/openshell-driver-vm/src/lifecycle.rs index 646070c3a1..5ab2ff01b8 100644 --- a/crates/openshell-driver-vm/src/lifecycle.rs +++ b/crates/openshell-driver-vm/src/lifecycle.rs @@ -32,6 +32,8 @@ pub enum LaunchAbortReason { /// opportunity to release host resources they allocated in /// [`LifecycleExtension::before_launch`]. ProcessExited, + /// The gateway intentionally suspended the sandbox while retaining disk state. + Suspended, } #[derive(Debug, Clone)] diff --git a/crates/openshell-driver-vm/src/otel_tracing.rs b/crates/openshell-driver-vm/src/otel_tracing.rs index fac2720cd7..df950b026c 100644 --- a/crates/openshell-driver-vm/src/otel_tracing.rs +++ b/crates/openshell-driver-vm/src/otel_tracing.rs @@ -74,6 +74,7 @@ fn compute_driver_rpc_operation(path: &str) -> (&'static str, &'static str) { Some("GetSandbox") => ("driver.get_sandbox", "get_sandbox"), Some("ListSandboxes") => ("driver.list_sandboxes", "list_sandboxes"), Some("StopSandbox") => ("driver.stop_sandbox", "stop_sandbox"), + Some("ResumeSandbox") => ("driver.resume_sandbox", "resume_sandbox"), Some("DeleteSandbox") => ("driver.delete_sandbox", "delete_sandbox"), Some("WatchSandboxes") => ("driver.watch_sandboxes", "watch_sandboxes"), _ => ("driver.unknown", "unknown"), @@ -177,6 +178,7 @@ mod tests { ("GetSandbox", "driver.get_sandbox", "get_sandbox"), ("ListSandboxes", "driver.list_sandboxes", "list_sandboxes"), ("StopSandbox", "driver.stop_sandbox", "stop_sandbox"), + ("ResumeSandbox", "driver.resume_sandbox", "resume_sandbox"), ("DeleteSandbox", "driver.delete_sandbox", "delete_sandbox"), ( "WatchSandboxes", diff --git a/crates/openshell-sdk/src/client.rs b/crates/openshell-sdk/src/client.rs index 0924ae4d62..b2c08ecf3a 100644 --- a/crates/openshell-sdk/src/client.rs +++ b/crates/openshell-sdk/src/client.rs @@ -217,6 +217,34 @@ impl OpenShellClient { Ok(response.deleted) } + /// Suspend a sandbox by name. + pub async fn suspend_sandbox(&self, name: &str) -> Result { + let response = self + .unary(|mut grpc| { + let request = proto::SuspendSandboxRequest { + name: name.to_string(), + workspace: String::new(), + }; + async move { grpc.suspend_sandbox(request).await } + }) + .await?; + sandbox_from_response(response.sandbox) + } + + /// Resume a suspended sandbox by name. + pub async fn resume_sandbox(&self, name: &str) -> Result { + let response = self + .unary(|mut grpc| { + let request = proto::ResumeSandboxRequest { + name: name.to_string(), + workspace: String::new(), + }; + async move { grpc.resume_sandbox(request).await } + }) + .await?; + sandbox_from_response(response.sandbox) + } + /// Poll [`OpenShellClient::get_sandbox`] until the sandbox reaches /// [`SandboxPhase::Ready`] or the `timeout` elapses. /// @@ -586,6 +614,36 @@ impl WorkspaceScopedClient { Ok(response.deleted) } + /// Suspend a sandbox by name in this workspace. + pub async fn suspend_sandbox(&self, name: &str) -> Result { + let response = self + .client + .unary(|mut grpc| { + let request = proto::SuspendSandboxRequest { + name: name.to_string(), + workspace: self.workspace.clone(), + }; + async move { grpc.suspend_sandbox(request).await } + }) + .await?; + sandbox_from_response(response.sandbox) + } + + /// Resume a suspended sandbox by name in this workspace. + pub async fn resume_sandbox(&self, name: &str) -> Result { + let response = self + .client + .unary(|mut grpc| { + let request = proto::ResumeSandboxRequest { + name: name.to_string(), + workspace: self.workspace.clone(), + }; + async move { grpc.resume_sandbox(request).await } + }) + .await?; + sandbox_from_response(response.sandbox) + } + /// Poll until the sandbox reaches [`SandboxPhase::Ready`] or the timeout /// elapses. pub async fn wait_ready(&self, name: &str, timeout: Duration) -> Result { diff --git a/crates/openshell-sdk/src/raw.rs b/crates/openshell-sdk/src/raw.rs index 80d7453602..4619d3d743 100644 --- a/crates/openshell-sdk/src/raw.rs +++ b/crates/openshell-sdk/src/raw.rs @@ -24,9 +24,9 @@ pub use openshell_core::proto::open_shell_client::OpenShellClient as GrpcClient; pub use openshell_core::proto::{ CreateSandboxRequest, CreateWorkspaceRequest, DeleteSandboxRequest, DeleteWorkspaceRequest, ExecSandboxRequest, GetSandboxRequest, GetWorkspaceRequest, HealthRequest, - ListProvidersRequest, ListSandboxesRequest, ListWorkspacesRequest, Sandbox, - SandboxPhase as ProtoSandboxPhase, SandboxSpec as ProtoSandboxSpec, SandboxTemplate, - ServiceStatus as ProtoServiceStatus, Workspace, + ListProvidersRequest, ListSandboxesRequest, ListWorkspacesRequest, ResumeSandboxRequest, + Sandbox, SandboxPhase as ProtoSandboxPhase, SandboxSpec as ProtoSandboxSpec, SandboxTemplate, + ServiceStatus as ProtoServiceStatus, SuspendSandboxRequest, Workspace, }; /// Type alias for the gRPC client wrapped in the SDK's auth interceptor. diff --git a/crates/openshell-sdk/src/types.rs b/crates/openshell-sdk/src/types.rs index 2eb4ef0a92..987201f33b 100644 --- a/crates/openshell-sdk/src/types.rs +++ b/crates/openshell-sdk/src/types.rs @@ -62,6 +62,9 @@ pub enum SandboxPhase { Error, Deleting, Unknown, + Suspending, + Suspended, + Resuming, } impl From for SandboxPhase { @@ -73,6 +76,9 @@ impl From for SandboxPhase { proto::SandboxPhase::Error => Self::Error, proto::SandboxPhase::Deleting => Self::Deleting, proto::SandboxPhase::Unknown => Self::Unknown, + proto::SandboxPhase::Suspending => Self::Suspending, + proto::SandboxPhase::Suspended => Self::Suspended, + proto::SandboxPhase::Resuming => Self::Resuming, } } } diff --git a/crates/openshell-sdk/tests/client_mock.rs b/crates/openshell-sdk/tests/client_mock.rs index 4ff23d74d1..aff6bf6829 100644 --- a/crates/openshell-sdk/tests/client_mock.rs +++ b/crates/openshell-sdk/tests/client_mock.rs @@ -31,6 +31,8 @@ struct MockState { last_create: Mutex>, last_delete_name: Mutex>, last_delete_workspace: Mutex>, + last_suspend: Mutex>, + last_resume: Mutex>, last_list_request: Mutex>, last_exec_request: Mutex>, last_workspace_request: Mutex>, @@ -161,6 +163,38 @@ impl OpenShell for TestOpenShell { })) } + async fn suspend_sandbox( + &self, + request: tonic::Request, + ) -> Result, Status> { + let request = request.into_inner(); + let sandbox = sandbox_with_phase_ws( + &request.name, + proto::SandboxPhase::Suspended, + &request.workspace, + ); + *self.state.last_suspend.lock().await = Some(request); + Ok(Response::new(proto::SandboxResponse { + sandbox: Some(sandbox), + })) + } + + async fn resume_sandbox( + &self, + request: tonic::Request, + ) -> Result, Status> { + let request = request.into_inner(); + let sandbox = sandbox_with_phase_ws( + &request.name, + proto::SandboxPhase::Resuming, + &request.workspace, + ); + *self.state.last_resume.lock().await = Some(request); + Ok(Response::new(proto::SandboxResponse { + sandbox: Some(sandbox), + })) + } + async fn get_sandbox( &self, request: tonic::Request, @@ -816,6 +850,29 @@ async fn delete_sandbox_returns_server_ack() { assert_eq!(observed.as_deref(), Some("doomed")); } +#[tokio::test] +async fn suspend_and_resume_map_requests_and_phases() { + let state = Arc::new(MockState::default()); + let endpoint = start_mock(state.clone()).await; + let client = connect(&endpoint).await; + + let suspended = client.suspend_sandbox("sleepy").await.unwrap(); + assert_eq!(suspended.phase, SandboxPhase::Suspended); + let suspend = state.last_suspend.lock().await.clone().unwrap(); + assert_eq!(suspend.name, "sleepy"); + assert!(suspend.workspace.is_empty()); + + let resumed = client + .workspace("team-a") + .resume_sandbox("sleepy") + .await + .unwrap(); + assert_eq!(resumed.phase, SandboxPhase::Resuming); + let resume = state.last_resume.lock().await.clone().unwrap(); + assert_eq!(resume.name, "sleepy"); + assert_eq!(resume.workspace, "team-a"); +} + #[tokio::test] async fn wait_ready_transitions_through_phases() { let state = Arc::new(MockState { diff --git a/crates/openshell-server/src/auth/method_authz.rs b/crates/openshell-server/src/auth/method_authz.rs index c06ca09f69..557e334e21 100644 --- a/crates/openshell-server/src/auth/method_authz.rs +++ b/crates/openshell-server/src/auth/method_authz.rs @@ -148,4 +148,18 @@ mod tests { // Unknown method falls through to AuthzPolicy::check. assert!(is_user_callable("/openshell.v1.OpenShell/FutureMethod")); } + + #[test] + fn sandbox_lifecycle_mutations_require_user_write_authority() { + for path in [ + "/openshell.v1.OpenShell/SuspendSandbox", + "/openshell.v1.OpenShell/ResumeSandbox", + ] { + let entry = lookup(path).expect("lifecycle RPC must have auth metadata"); + assert_eq!(entry.auth_mode, AuthMode::Bearer); + assert_eq!(entry.scope.as_deref(), Some("sandbox:write")); + assert_eq!(entry.workspace_role.as_deref(), Some("user")); + assert!(!is_sandbox_callable(path)); + } + } } diff --git a/crates/openshell-server/src/auth/sandbox_methods.rs b/crates/openshell-server/src/auth/sandbox_methods.rs index a74b1280ce..9fb46c68fd 100644 --- a/crates/openshell-server/src/auth/sandbox_methods.rs +++ b/crates/openshell-server/src/auth/sandbox_methods.rs @@ -42,6 +42,12 @@ mod tests { assert!(!is_sandbox_callable( "/openshell.v1.OpenShell/DeleteSandbox" )); + assert!(!is_sandbox_callable( + "/openshell.v1.OpenShell/SuspendSandbox" + )); + assert!(!is_sandbox_callable( + "/openshell.v1.OpenShell/ResumeSandbox" + )); assert!(!is_sandbox_callable( "/openshell.v1.OpenShell/CreateProvider" )); diff --git a/crates/openshell-server/src/compute/mod.rs b/crates/openshell-server/src/compute/mod.rs index a1c33e49ff..350abf1095 100644 --- a/crates/openshell-server/src/compute/mod.rs +++ b/crates/openshell-server/src/compute/mod.rs @@ -32,10 +32,10 @@ use openshell_core::proto::compute::v1::{ GetCapabilitiesRequest, GetGatewayListenerRequirementsRequest, GetGatewayListenerRequirementsResponse, GetSandboxRequest, GpuResourceRequirements as DriverGpuResourceRequirements, ListSandboxesRequest, - ResourceRequirements as DriverSandboxResourceRequirements, ValidateSandboxCreateRequest, - WatchSandboxesEvent, WatchSandboxesRequest, compute_driver_client::ComputeDriverClient, - compute_driver_server::ComputeDriver, gateway_listener_requirement::Selector, - watch_sandboxes_event, + ResourceRequirements as DriverSandboxResourceRequirements, ResumeSandboxRequest, + StopSandboxRequest, ValidateSandboxCreateRequest, WatchSandboxesEvent, WatchSandboxesRequest, + compute_driver_client::ComputeDriverClient, compute_driver_server::ComputeDriver, + gateway_listener_requirement::Selector, watch_sandboxes_event, }; use openshell_core::proto::{ PlatformEvent, Sandbox, SandboxCondition, SandboxPhase, SandboxSpec, SandboxStatus, @@ -168,20 +168,20 @@ impl GatewayListenerRequirement { } } -/// Serializes request-side deletes for the same stable sandbox ID. +/// Serializes request-side lifecycle mutations for the same stable sandbox ID. /// /// Watch events deliberately do not use these gates, so a slow driver delete /// cannot block the sequential watch loop. Weak values let entries disappear /// after the last request using a sandbox's gate completes. #[derive(Debug, Default)] -struct DeleteGateRegistry { +struct LifecycleGateRegistry { gates: StdMutex>>>, } -impl DeleteGateRegistry { - async fn lock_for(&self, sandbox_id: &str) -> SandboxDeleteGuard { +impl LifecycleGateRegistry { + async fn lock_for(&self, sandbox_id: &str) -> SandboxLifecycleGuard { let gate = self.gate_for(sandbox_id); - SandboxDeleteGuard { + SandboxLifecycleGuard { _guard: gate.lock_owned().await, } } @@ -190,7 +190,7 @@ impl DeleteGateRegistry { let mut gates = self .gates .lock() - .expect("sandbox delete gate registry lock poisoned"); + .expect("sandbox lifecycle gate registry lock poisoned"); gates.retain(|_, gate| gate.strong_count() > 0); if let Some(gate) = gates.get(sandbox_id).and_then(Weak::upgrade) { @@ -206,18 +206,18 @@ impl DeleteGateRegistry { fn entry_count(&self) -> usize { self.gates .lock() - .expect("sandbox delete gate registry lock poisoned") + .expect("sandbox lifecycle gate registry lock poisoned") .len() } } -/// Proof that the current delete operation holds its sandbox-ID gate. +/// Proof that the current operation holds its sandbox-ID lifecycle gate. /// -/// Delete code must acquire this guard before taking `ComputeRuntime::sync_lock`. -/// Passing it to `lock_global_for_delete` makes that ordering visible at every -/// global-lock acquisition in the delete path. +/// Lifecycle code must acquire this guard before taking `ComputeRuntime::sync_lock`. +/// Passing it to `lock_global_for_lifecycle` makes that ordering visible at +/// every global-lock acquisition in a lifecycle path. #[derive(Debug)] -struct SandboxDeleteGuard { +struct SandboxLifecycleGuard { _guard: tokio::sync::OwnedMutexGuard<()>, } @@ -517,13 +517,22 @@ impl ComputeDriver for RemoteComputeDriver { async fn stop_sandbox( &self, - request: Request, + request: Request, ) -> Result, Status> { let mut client = self.client(); client.stop_sandbox(request).await } + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> + { + let mut client = self.client(); + client.resume_sandbox(request).await + } + async fn delete_sandbox( &self, request: Request, @@ -558,7 +567,7 @@ pub struct ComputeRuntime { tracing_log_bus: TracingLogBus, supervisor_sessions: Arc, sync_lock: Arc>, - delete_gates: Arc, + lifecycle_gates: Arc, gateway_listener_requirements: Vec, replica_id: String, } @@ -679,7 +688,7 @@ impl ComputeRuntime { tracing_log_bus, supervisor_sessions, sync_lock: Arc::new(Mutex::new(())), - delete_gates: Arc::new(DeleteGateRegistry::default()), + lifecycle_gates: Arc::new(LifecycleGateRegistry::default()), gateway_listener_requirements, replica_id: lease::replica_id(), }) @@ -696,18 +705,18 @@ impl ComputeRuntime { } /// Acquires the process-wide lock for code that already holds the - /// sandbox-ID delete gate. The guard parameter documents and enforces that - /// delete-path callers acquire locks in delete-gate -> global-lock order. - async fn lock_global_for_delete( + /// sandbox-ID lifecycle gate. The guard parameter documents and enforces + /// that callers acquire locks in lifecycle-gate -> global-lock order. + async fn lock_global_for_lifecycle( &self, - _delete_guard: &SandboxDeleteGuard, + _lifecycle_guard: &SandboxLifecycleGuard, ) -> tokio::sync::OwnedMutexGuard<()> { self.sync_lock.clone().lock_owned().await } #[cfg(test)] - pub(crate) fn delete_gate_entry_count(&self) -> usize { - self.delete_gates.entry_count() + pub(crate) fn lifecycle_gate_entry_count(&self) -> usize { + self.lifecycle_gates.entry_count() } pub async fn new_docker( @@ -963,6 +972,431 @@ impl ComputeRuntime { } } + pub(crate) async fn suspend_sandbox( + &self, + workspace: &str, + name: &str, + ) -> Result { + let candidate = self + .store + .get_message_by_name::(workspace, name) + .await + .map_err(|e| Status::internal(format!("fetch sandbox failed: {e}")))? + .ok_or_else(|| Status::not_found("sandbox not found"))?; + let sandbox_id = candidate.object_id().to_string(); + let sandbox_name = candidate.object_name().to_string(); + let lifecycle_guard = self.lifecycle_gates.lock_for(&sandbox_id).await; + let global_guard = self.lock_global_for_lifecycle(&lifecycle_guard).await; + let current = self + .store + .get_message::(&sandbox_id) + .await + .map_err(|e| Status::internal(format!("fetch sandbox failed: {e}")))? + .ok_or_else(|| Status::not_found("sandbox not found"))?; + if current.object_name() != sandbox_name { + return Err(Status::aborted( + "sandbox name changed while the suspend request was waiting; retry explicitly", + )); + } + + let phase = SandboxPhase::try_from(current.phase()).unwrap_or(SandboxPhase::Unknown); + if phase == SandboxPhase::Suspended { + self.cleanup_suspended_sandbox_sessions(¤t) + .await + .map_err(Status::internal)?; + return Ok(current); + } + if !matches!(phase, SandboxPhase::Ready | SandboxPhase::Suspending) { + return Err(Status::failed_precondition(format!( + "sandbox must be Ready to suspend (current phase: {phase:?})" + ))); + } + + let (previous, suspending) = if phase == SandboxPhase::Suspending { + // Acquiring the lifecycle gate proves that no local worker still + // owns this transition. Retry the idempotent driver operation. + (current.clone(), current) + } else { + let previous = current.clone(); + let suspending = self + .write_lifecycle_phase( + ¤t, + SandboxPhase::Suspending, + "Suspending", + "Sandbox suspension requested", + ) + .await?; + self.sandbox_index.update_from_sandbox(&suspending); + self.sandbox_watch_bus.notify(&sandbox_id); + (previous, suspending) + }; + drop(global_guard); + + // Once the durable transition is committed, request cancellation must + // not cancel the driver operation and strand the sandbox in + // `Suspending`. Keep the lifecycle gate in an owned worker, matching + // the delete path's cancellation semantics. + let runtime = self.clone(); + let request_span = tracing::Span::current(); + tokio::spawn( + async move { + runtime + .complete_sandbox_suspend( + sandbox_id, + sandbox_name, + previous, + suspending, + lifecycle_guard, + ) + .await + } + .instrument(request_span), + ) + .await + .map_err(|err| { + Status::internal(format!( + "sandbox suspend worker terminated unexpectedly: {err}" + )) + })? + } + + async fn complete_sandbox_suspend( + &self, + sandbox_id: String, + sandbox_name: String, + previous: Sandbox, + suspending: Sandbox, + lifecycle_guard: SandboxLifecycleGuard, + ) -> Result { + let result = self + .driver + .call("driver.stop_sandbox", Some(&sandbox_id), |driver| { + let sandbox_id = sandbox_id.clone(); + let sandbox_name = sandbox_name.clone(); + async move { + driver + .stop_sandbox(Request::new(StopSandboxRequest { + sandbox_id, + sandbox_name, + })) + .await + } + }) + .await; + + match result { + Ok(_) => { + let _global_guard = self.lock_global_for_lifecycle(&lifecycle_guard).await; + let latest = self + .store + .get_message::(&sandbox_id) + .await + .map_err(|e| Status::internal(format!("fetch sandbox failed: {e}")))? + .ok_or_else(|| Status::not_found("sandbox not found"))?; + let phase = SandboxPhase::try_from(latest.phase()).unwrap_or(SandboxPhase::Unknown); + let suspended = if phase == SandboxPhase::Suspended { + latest + } else if phase == SandboxPhase::Suspending { + self.write_lifecycle_phase( + &latest, + SandboxPhase::Suspended, + "Suspended", + "Sandbox compute is stopped", + ) + .await? + } else { + return Err(Status::aborted( + "sandbox lifecycle changed while suspension completed", + )); + }; + self.cleanup_suspended_sandbox_sessions(&suspended) + .await + .map_err(Status::internal)?; + self.sandbox_index.update_from_sandbox(&suspended); + self.sandbox_watch_bus.notify(&sandbox_id); + Ok(suspended) + } + Err(err) => { + self.recover_failed_lifecycle(&lifecycle_guard, &suspending, &previous, true) + .await; + Err(Status::new( + err.code(), + format!("suspend sandbox failed: {}", err.message()), + )) + } + } + } + + pub(crate) async fn resume_sandbox( + &self, + workspace: &str, + name: &str, + ) -> Result { + let candidate = self + .store + .get_message_by_name::(workspace, name) + .await + .map_err(|e| Status::internal(format!("fetch sandbox failed: {e}")))? + .ok_or_else(|| Status::not_found("sandbox not found"))?; + let sandbox_id = candidate.object_id().to_string(); + let sandbox_name = candidate.object_name().to_string(); + let lifecycle_guard = self.lifecycle_gates.lock_for(&sandbox_id).await; + let global_guard = self.lock_global_for_lifecycle(&lifecycle_guard).await; + let current = self + .store + .get_message::(&sandbox_id) + .await + .map_err(|e| Status::internal(format!("fetch sandbox failed: {e}")))? + .ok_or_else(|| Status::not_found("sandbox not found"))?; + if current.object_name() != sandbox_name { + return Err(Status::aborted( + "sandbox name changed while the resume request was waiting; retry explicitly", + )); + } + + let phase = SandboxPhase::try_from(current.phase()).unwrap_or(SandboxPhase::Unknown); + if phase == SandboxPhase::Ready { + return Ok(current); + } + if !matches!(phase, SandboxPhase::Suspended | SandboxPhase::Resuming) { + return Err(Status::failed_precondition(format!( + "sandbox must be Suspended to resume (current phase: {phase:?})" + ))); + } + + let (previous, resuming) = if phase == SandboxPhase::Resuming { + // Acquiring the lifecycle gate proves that no local worker still + // owns this transition. Retry the idempotent driver operation. + (current.clone(), current) + } else { + let previous = current.clone(); + let resuming = self + .write_lifecycle_phase( + ¤t, + SandboxPhase::Resuming, + "Resuming", + "Sandbox resume requested", + ) + .await?; + self.sandbox_index.update_from_sandbox(&resuming); + self.sandbox_watch_bus.notify(&sandbox_id); + (previous, resuming) + }; + drop(global_guard); + + // The durable `Resuming` transition commits the operation. Let an + // owned worker finish it even if the initiating RPC is canceled. + let runtime = self.clone(); + let request_span = tracing::Span::current(); + tokio::spawn( + async move { + runtime + .complete_sandbox_resume( + sandbox_id, + sandbox_name, + previous, + resuming, + lifecycle_guard, + ) + .await + } + .instrument(request_span), + ) + .await + .map_err(|err| { + Status::internal(format!( + "sandbox resume worker terminated unexpectedly: {err}" + )) + })? + } + + async fn complete_sandbox_resume( + &self, + sandbox_id: String, + sandbox_name: String, + previous: Sandbox, + resuming: Sandbox, + lifecycle_guard: SandboxLifecycleGuard, + ) -> Result { + let result = self + .driver + .call("driver.resume_sandbox", Some(&sandbox_id), |driver| { + let sandbox_id = sandbox_id.clone(); + let sandbox_name = sandbox_name.clone(); + async move { + driver + .resume_sandbox(Request::new(ResumeSandboxRequest { + sandbox_id, + sandbox_name, + })) + .await + } + }) + .await; + + match result { + Ok(_) => { + let _global_guard = self.lock_global_for_lifecycle(&lifecycle_guard).await; + let latest = self + .store + .get_message::(&sandbox_id) + .await + .map_err(|e| Status::internal(format!("fetch sandbox failed: {e}")))? + .ok_or_else(|| Status::not_found("sandbox not found"))?; + Ok(latest) + } + Err(err) => { + self.recover_failed_lifecycle(&lifecycle_guard, &resuming, &previous, false) + .await; + Err(Status::new( + err.code(), + format!("resume sandbox failed: {}", err.message()), + )) + } + } + } + + /// Reconcile an ambiguous lifecycle error against the driver's observed + /// state before deciding whether the pre-operation snapshot is still true. + /// + /// A transport error can arrive after the runtime applied stop or start. + /// The driver lookup deliberately runs without the process-wide lock; the + /// exact transition resource version then fences the recovery write. + async fn recover_failed_lifecycle( + &self, + lifecycle_guard: &SandboxLifecycleGuard, + transition: &Sandbox, + previous: &Sandbox, + expected_stopped: bool, + ) { + let sandbox_id = transition.object_id(); + let sandbox_name = transition.object_name(); + let observed = self.get_driver_sandbox(sandbox_id, sandbox_name).await; + let _global_guard = self.lock_global_for_lifecycle(lifecycle_guard).await; + + match observed { + Ok(Some(snapshot)) if snapshot.id == sandbox_id && snapshot.status.is_some() => { + let backend_phase = derive_phase(snapshot.status.as_ref()); + let observed_stopped = backend_phase == SandboxPhase::Suspended + || driver_snapshot_confirms_stopped(&snapshot); + if backend_phase == SandboxPhase::Error || observed_stopped == expected_stopped { + if let Some(reconciled) = self + .reconcile_lifecycle_snapshot(transition, &snapshot) + .await + && reconciled.phase() == SandboxPhase::Suspended as i32 + && let Err(err) = self.cleanup_suspended_sandbox_sessions(&reconciled).await + { + warn!( + sandbox_id, + error = %err, + "Failed to clean up sessions after reconciling suspended sandbox" + ); + } + } else { + self.restore_lifecycle_snapshot(transition, previous).await; + } + } + Ok(Some(_) | None) | Err(_) => { + // Without authoritative backend state, retain the durable + // transition rather than claiming the old running/stopped + // state. Startup recovery can safely retry the idempotent + // driver operation. + warn!( + sandbox_id, + "Could not resolve ambiguous sandbox lifecycle outcome; retaining transition" + ); + } + } + } + + async fn reconcile_lifecycle_snapshot( + &self, + transition: &Sandbox, + snapshot: &DriverSandbox, + ) -> Option { + let sandbox_id = transition.object_id().to_string(); + let expected_resource_version = sandbox_resource_version(transition); + let session_connected = self.supervisor_sessions.has_session(&sandbox_id); + match self + .store + .update_message_cas::(&sandbox_id, expected_resource_version, |sandbox| { + apply_driver_snapshot(sandbox, snapshot, session_connected); + }) + .await + { + Ok(reconciled) => { + self.sandbox_index.update_from_sandbox(&reconciled); + self.sandbox_watch_bus.notify(&sandbox_id); + Some(reconciled) + } + Err(err) => { + debug!( + sandbox_id, + error = %err, + "Skipped lifecycle reconciliation after concurrent change" + ); + None + } + } + } + + async fn write_lifecycle_phase( + &self, + sandbox: &Sandbox, + phase: SandboxPhase, + reason: &str, + message: &str, + ) -> Result { + let sandbox_id = sandbox.object_id().to_string(); + let expected_resource_version = sandbox_resource_version(sandbox); + let reason = reason.to_string(); + let message = message.to_string(); + self.store + .update_message_cas::( + &sandbox_id, + expected_resource_version, + move |sandbox| { + sandbox.set_phase(phase as i32); + let name = sandbox.object_name().to_string(); + upsert_ready_condition( + &mut sandbox.status, + &name, + SandboxCondition { + r#type: "Ready".to_string(), + status: "False".to_string(), + reason: reason.clone(), + message: message.clone(), + last_transition_time: String::new(), + }, + ); + }, + ) + .await + .map_err(|e| crate::grpc::persistence_error_to_status(e, "update sandbox lifecycle")) + } + + async fn restore_lifecycle_snapshot(&self, owned: &Sandbox, previous: &Sandbox) { + let sandbox_id = owned.object_id().to_string(); + let previous = previous.clone(); + match self + .store + .update_message_cas::( + &sandbox_id, + sandbox_resource_version(owned), + move |sandbox| *sandbox = previous.clone(), + ) + .await + { + Ok(restored) => { + self.sandbox_index.update_from_sandbox(&restored); + self.sandbox_watch_bus.notify(&sandbox_id); + } + Err(err) => { + debug!(sandbox_id, error = %err, "Skipped lifecycle rollback after concurrent change"); + } + } + } + pub(crate) async fn delete_sandbox( &self, workspace: &str, @@ -981,8 +1415,8 @@ impl ComputeRuntime { sandbox_id: candidate.object_id().to_string(), sandbox_name: candidate.object_name().to_string(), }; - let delete_guard = self.delete_gates.lock_for(&target.sandbox_id).await; - let global_guard = self.lock_global_for_delete(&delete_guard).await; + let delete_guard = self.lifecycle_gates.lock_for(&target.sandbox_id).await; + let global_guard = self.lock_global_for_lifecycle(&delete_guard).await; // There is no await between acquiring the initial guards and spawning // the worker. From this commitment point onward, request cancellation @@ -1010,7 +1444,7 @@ impl ComputeRuntime { async fn delete_sandbox_inner( &self, target: SandboxDeleteTarget, - delete_guard: SandboxDeleteGuard, + delete_guard: SandboxLifecycleGuard, guard: tokio::sync::OwnedMutexGuard<()>, ) -> Result { let current = self @@ -1176,10 +1610,10 @@ impl ComputeRuntime { /// row leaves `Deleting`; that state belongs to a concurrent writer. async fn remove_deleting_sandbox_record( &self, - delete_guard: &SandboxDeleteGuard, + delete_guard: &SandboxLifecycleGuard, sandbox_id: &str, ) -> bool { - let _guard = self.lock_global_for_delete(delete_guard).await; + let _guard = self.lock_global_for_lifecycle(delete_guard).await; for attempt in 1..=DELETE_PHASE_CAS_RETRY_LIMIT { let record = match self.store.get(Sandbox::object_type(), sandbox_id).await { Ok(Some(record)) => record, @@ -1310,7 +1744,7 @@ impl ComputeRuntime { /// backend, or restore the pre-delete snapshot when lookup is inconclusive. async fn recover_failed_delete( &self, - delete_guard: &SandboxDeleteGuard, + delete_guard: &SandboxLifecycleGuard, transition: &DeleteTransition, ) { let sandbox_id = transition.deleting.object_id(); @@ -1319,7 +1753,7 @@ impl ComputeRuntime { // The driver lookup is deliberately outside the process-wide guard. let observed = self.get_driver_sandbox(sandbox_id, sandbox_name).await; - let _guard = self.lock_global_for_delete(delete_guard).await; + let _guard = self.lock_global_for_lifecycle(delete_guard).await; match observed { Ok(Some(snapshot)) if snapshot.id == sandbox_id && snapshot.status.is_some() => { @@ -1581,6 +2015,7 @@ impl ComputeRuntime { /// Should be called once at gateway startup, before watchers spawn, /// so the watch loop sees the post-resume state on its first poll. pub async fn resume_persisted_sandboxes(&self) -> Result<(), String> { + self.recover_persisted_lifecycle_transitions().await?; let Some(resume) = &self.startup_resume else { return Ok(()); }; @@ -1670,34 +2105,131 @@ impl ComputeRuntime { Ok(()) } - async fn mark_sandbox_error(&self, sandbox: &Sandbox, reason: &str, message: &str) { - let _guard = self.sync_lock.lock().await; - let sandbox_id = sandbox.object_id().to_string(); - let reason = reason.to_string(); - let message = message.to_string(); - match self + async fn recover_persisted_lifecycle_transitions(&self) -> Result<(), String> { + let records = self .store - .update_message_cas::(&sandbox_id, 0, |s| { - s.set_phase(SandboxPhase::Error as i32); - let name = s.object_name().to_string(); - upsert_ready_condition( - &mut s.status, - &name, - SandboxCondition { - r#type: "Ready".to_string(), - status: "False".to_string(), - reason: reason.clone(), - message: message.clone(), - last_transition_time: String::new(), - }, - ); - }) + .list_by_type(Sandbox::object_type(), 1000, 0) .await - { - Ok(updated) => { - self.sandbox_index.update_from_sandbox(&updated); - self.sandbox_watch_bus.notify(&sandbox_id); - } + .map_err(|e| e.to_string())?; + for record in records { + let sandbox = match Sandbox::decode(record.payload.as_slice()) { + Ok(sandbox) => sandbox, + Err(err) => { + warn!(error = %err, "Failed to decode sandbox during lifecycle recovery"); + continue; + } + }; + let phase = SandboxPhase::try_from(sandbox.phase()).unwrap_or(SandboxPhase::Unknown); + match phase { + SandboxPhase::Suspended => { + if let Err(err) = self.cleanup_suspended_sandbox_sessions(&sandbox).await { + warn!(sandbox_id = %sandbox.object_id(), error = %err, "Failed to complete recovered sandbox session cleanup"); + } + } + SandboxPhase::Suspending => { + let sandbox_id = sandbox.object_id().to_string(); + let sandbox_name = sandbox.object_name().to_string(); + let driver_sandbox_id = sandbox_id.clone(); + match self + .driver + .call( + "driver.stop_sandbox", + Some(&sandbox_id), + |driver| async move { + driver + .stop_sandbox(Request::new(StopSandboxRequest { + sandbox_id: driver_sandbox_id, + sandbox_name, + })) + .await + }, + ) + .await + { + Ok(_) => match self + .write_lifecycle_phase( + &sandbox, + SandboxPhase::Suspended, + "Suspended", + "Sandbox compute is stopped", + ) + .await + { + Ok(updated) => { + self.sandbox_index.update_from_sandbox(&updated); + self.sandbox_watch_bus.notify(updated.object_id()); + if let Err(err) = + self.cleanup_suspended_sandbox_sessions(&updated).await + { + warn!(sandbox_id = %updated.object_id(), error = %err, "Failed to complete recovered sandbox session cleanup"); + } + } + Err(err) => { + warn!(sandbox_id = %sandbox.object_id(), error = %err, "Failed to persist recovered suspension"); + } + }, + Err(err) => { + warn!(sandbox_id = %sandbox.object_id(), error = %err, "Failed to recover sandbox suspension"); + } + } + } + SandboxPhase::Resuming => { + let sandbox_id = sandbox.object_id().to_string(); + let sandbox_name = sandbox.object_name().to_string(); + let driver_sandbox_id = sandbox_id.clone(); + if let Err(err) = self + .driver + .call( + "driver.resume_sandbox", + Some(&sandbox_id), + |driver| async move { + driver + .resume_sandbox(Request::new(ResumeSandboxRequest { + sandbox_id: driver_sandbox_id, + sandbox_name, + })) + .await + }, + ) + .await + { + warn!(sandbox_id = %sandbox.object_id(), error = %err, "Failed to recover sandbox resume"); + } + } + _ => {} + } + } + Ok(()) + } + + async fn mark_sandbox_error(&self, sandbox: &Sandbox, reason: &str, message: &str) { + let _guard = self.sync_lock.lock().await; + let sandbox_id = sandbox.object_id().to_string(); + let reason = reason.to_string(); + let message = message.to_string(); + match self + .store + .update_message_cas::(&sandbox_id, 0, |s| { + s.set_phase(SandboxPhase::Error as i32); + let name = s.object_name().to_string(); + upsert_ready_condition( + &mut s.status, + &name, + SandboxCondition { + r#type: "Ready".to_string(), + status: "False".to_string(), + reason: reason.clone(), + message: message.clone(), + last_transition_time: String::new(), + }, + ); + }) + .await + { + Ok(updated) => { + self.sandbox_index.update_from_sandbox(&updated); + self.sandbox_watch_bus.notify(&sandbox_id); + } Err(err) => { warn!( sandbox_id = %sandbox_id, @@ -2101,7 +2633,13 @@ impl ComputeRuntime { }; let current_phase = SandboxPhase::try_from(existing.phase()).unwrap_or(SandboxPhase::Unknown); - if current_phase == SandboxPhase::Deleting || current_phase == SandboxPhase::Error { + if matches!( + current_phase, + SandboxPhase::Deleting + | SandboxPhase::Error + | SandboxPhase::Suspending + | SandboxPhase::Suspended + ) { return Ok(()); } if !connected && current_phase != SandboxPhase::Ready { @@ -2237,6 +2775,16 @@ impl ComputeRuntime { Ok(()) } + async fn cleanup_suspended_sandbox_sessions(&self, sandbox: &Sandbox) -> Result<(), String> { + // Disconnect first so a store failure cannot leave the stopped + // sandbox reachable through an existing supervisor stream. Both + // operations are idempotent and are retried for durable Suspended + // records during explicit suspend requests and startup recovery. + self.supervisor_sessions.disconnect(sandbox.object_id()); + self.cleanup_sandbox_ssh_sessions(sandbox.object_id(), sandbox.object_workspace()) + .await + } + // TODO: introduce a per-sandbox cap on service endpoints and paginate // this cleanup loop, or query by sandbox label instead of scanning the // full workspace. Without a cap the flat 1,000-record page could miss @@ -2270,10 +2818,10 @@ impl ComputeRuntime { async fn cleanup_local_state_if_sandbox_absent( &self, - delete_guard: &SandboxDeleteGuard, + delete_guard: &SandboxLifecycleGuard, sandbox_id: &str, ) -> Result<(), Status> { - let _guard = self.lock_global_for_delete(delete_guard).await; + let _guard = self.lock_global_for_lifecycle(delete_guard).await; let record = self .store .get(Sandbox::object_type(), sandbox_id) @@ -2405,6 +2953,45 @@ impl ComputeRuntime { } let sandbox = decode_sandbox_record(¤t_record)?; + let phase = SandboxPhase::try_from(sandbox.phase()).unwrap_or(SandboxPhase::Unknown); + if matches!( + phase, + SandboxPhase::Suspending | SandboxPhase::Suspended | SandboxPhase::Resuming + ) { + let updated = self + .store + .update_message_cas::( + &sandbox_id, + expected_resource_version, + |sandbox| { + sandbox.set_phase(SandboxPhase::Error as i32); + let name = sandbox.object_name().to_string(); + upsert_ready_condition( + &mut sandbox.status, + &name, + SandboxCondition { + r#type: "Ready".to_string(), + status: "False".to_string(), + reason: "ComputeResourceMissing".to_string(), + message: "The compute driver could not find the retained sandbox resource; delete the sandbox to clean up its remaining state" + .to_string(), + last_transition_time: String::new(), + }, + ); + }, + ) + .await + .map_err(|err| err.to_string())?; + warn!( + sandbox_id = %sandbox_id, + sandbox_name = %sandbox_name, + phase = ?phase, + "Retained sandbox resource disappeared from the compute driver" + ); + self.sandbox_index.update_from_sandbox(&updated); + self.sandbox_watch_bus.notify(&sandbox_id); + return Ok(()); + } info!( sandbox_id = %sandbox_id, sandbox_name = %sandbox_name, @@ -2811,7 +3398,7 @@ fn apply_driver_snapshot(sandbox: &mut Sandbox, incoming: &DriverSandbox, sessio let sandbox_name = &incoming.name; let cpv = sandbox.current_policy_version(); - let (phase, mut status) = incoming.status.as_ref().map_or_else( + let (mut phase, mut status) = incoming.status.as_ref().map_or_else( || { let mut phase = old_phase; let supervisor_promoted = session_connected @@ -2839,6 +3426,24 @@ fn apply_driver_snapshot(sandbox: &mut Sandbox, incoming: &DriverSandbox, sessio }, ); + phase = match old_phase { + SandboxPhase::Suspending + if phase == SandboxPhase::Suspended || driver_snapshot_confirms_stopped(incoming) => + { + SandboxPhase::Suspended + } + SandboxPhase::Suspending if phase != SandboxPhase::Error => SandboxPhase::Suspending, + SandboxPhase::Suspended => SandboxPhase::Suspended, + SandboxPhase::Resuming if !matches!(phase, SandboxPhase::Ready | SandboxPhase::Error) => { + SandboxPhase::Resuming + } + _ => phase, + }; + + if let Some(status) = status.as_mut() { + status.phase = phase as i32; + } + if let Some(status) = status.as_mut() && status.sandbox_name.is_empty() { @@ -2882,6 +3487,18 @@ fn apply_driver_snapshot(sandbox: &mut Sandbox, incoming: &DriverSandbox, sessio sandbox.set_current_policy_version(cpv); } +fn driver_snapshot_confirms_stopped(incoming: &DriverSandbox) -> bool { + incoming.status.as_ref().is_some_and(|status| { + status.conditions.iter().any(|condition| { + condition.status.eq_ignore_ascii_case("false") + && matches!( + condition.reason.to_ascii_lowercase().as_str(), + "containerexited" | "containerstopped" + ) + }) + }) +} + fn ensure_supervisor_ready_status(status: &mut Option, sandbox_name: &str) { upsert_ready_condition( status, @@ -2916,7 +3533,7 @@ impl ComposedPhase { // before this driver snapshot arrived. Keep Ready rather than letting a lagging // backend phase overwrite it. let phase = match backend_phase { - SandboxPhase::Error | SandboxPhase::Deleting => backend_phase, + SandboxPhase::Error | SandboxPhase::Deleting | SandboxPhase::Suspended => backend_phase, _ if session_connected => SandboxPhase::Ready, _ => SandboxPhase::Provisioning, }; @@ -3019,6 +3636,13 @@ fn derive_phase(status: Option<&DriverSandboxStatus>) -> SandboxPhase { return SandboxPhase::Deleting; } + if status.conditions.iter().any(|condition| { + condition.r#type.eq_ignore_ascii_case("Suspended") + && condition.status.eq_ignore_ascii_case("true") + }) { + return SandboxPhase::Suspended; + } + for condition in &status.conditions { if condition.r#type == "Ready" { return if condition.status.eq_ignore_ascii_case("true") { @@ -3072,6 +3696,7 @@ fn sandbox_phase_should_be_running(phase: SandboxPhase) -> bool { SandboxPhase::Unspecified | SandboxPhase::Provisioning | SandboxPhase::Ready + | SandboxPhase::Resuming | SandboxPhase::Unknown ) } @@ -3167,7 +3792,7 @@ impl ComputeDriver for NoopTestDriver { async fn stop_sandbox( &self, - _request: Request, + _request: Request, ) -> Result, Status> { Ok(tonic::Response::new( @@ -3175,6 +3800,16 @@ impl ComputeDriver for NoopTestDriver { )) } + async fn resume_sandbox( + &self, + _request: Request, + ) -> Result, Status> + { + Ok(tonic::Response::new( + openshell_core::proto::compute::v1::ResumeSandboxResponse {}, + )) + } + async fn delete_sandbox( &self, _request: Request, @@ -3217,7 +3852,7 @@ pub async fn new_test_runtime_for_driver(store: Arc, driver_name: &str) - tracing_log_bus: TracingLogBus::new(), supervisor_sessions: Arc::new(SupervisorSessionRegistry::new()), sync_lock: Arc::new(Mutex::new(())), - delete_gates: Arc::new(DeleteGateRegistry::default()), + lifecycle_gates: Arc::new(LifecycleGateRegistry::default()), gateway_listener_requirements: Vec::new(), replica_id: "test-replica".to_string(), } @@ -3229,8 +3864,8 @@ mod tests { use futures::stream; use openshell_core::proto::compute::v1::{ CreateSandboxResponse, DeleteSandboxResponse, GetCapabilitiesResponse, GetSandboxRequest, - GetSandboxResponse, StopSandboxRequest, StopSandboxResponse, ValidateSandboxCreateResponse, - WatchSandboxesDeletedEvent, WatchSandboxesSandboxEvent, + GetSandboxResponse, ResumeSandboxResponse, StopSandboxRequest, StopSandboxResponse, + ValidateSandboxCreateResponse, WatchSandboxesDeletedEvent, WatchSandboxesSandboxEvent, }; use std::collections::HashMap; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; @@ -3446,6 +4081,13 @@ mod tests { Ok(tonic::Response::new(StopSandboxResponse {})) } + async fn resume_sandbox( + &self, + _request: Request, + ) -> Result, Status> { + Ok(tonic::Response::new(ResumeSandboxResponse {})) + } + async fn delete_sandbox( &self, _request: Request, @@ -3476,6 +4118,12 @@ mod tests { Error(&'static str), } + #[derive(Clone)] + enum ControlledLifecycleOutcome { + Ok, + Error(&'static str), + } + struct ControlledDriver { watch_tx: mpsc::UnboundedSender>, watch_rx: TestMutex>>>, @@ -3485,6 +4133,18 @@ mod tests { delete_blocked: AtomicBool, delete_calls: AtomicUsize, delete_outcome: TestMutex, + stop_started: Notify, + stop_finished: Notify, + stop_release: Semaphore, + stop_blocked: AtomicBool, + stop_calls: AtomicUsize, + stop_outcome: TestMutex, + resume_started: Notify, + resume_finished: Notify, + resume_release: Semaphore, + resume_blocked: AtomicBool, + resume_calls: AtomicUsize, + resume_outcome: TestMutex, get_started: Notify, get_release: Semaphore, get_blocked: AtomicBool, @@ -3503,6 +4163,18 @@ mod tests { delete_blocked: AtomicBool::new(false), delete_calls: AtomicUsize::new(0), delete_outcome: TestMutex::new(ControlledDeleteOutcome::Ok(true)), + stop_started: Notify::new(), + stop_finished: Notify::new(), + stop_release: Semaphore::new(0), + stop_blocked: AtomicBool::new(false), + stop_calls: AtomicUsize::new(0), + stop_outcome: TestMutex::new(ControlledLifecycleOutcome::Ok), + resume_started: Notify::new(), + resume_finished: Notify::new(), + resume_release: Semaphore::new(0), + resume_blocked: AtomicBool::new(false), + resume_calls: AtomicUsize::new(0), + resume_outcome: TestMutex::new(ControlledLifecycleOutcome::Ok), get_started: Notify::new(), get_release: Semaphore::new(0), get_blocked: AtomicBool::new(false), @@ -3518,6 +4190,22 @@ mod tests { self.delete_release.add_permits(1); } + fn block_stop(&self) { + self.stop_blocked.store(true, Ordering::SeqCst); + } + + fn release_stop(&self) { + self.stop_release.add_permits(1); + } + + fn block_resume(&self) { + self.resume_blocked.store(true, Ordering::SeqCst); + } + + fn release_resume(&self) { + self.resume_release.add_permits(1); + } + fn block_get(&self) { self.get_blocked.store(true, Ordering::SeqCst); } @@ -3533,6 +4221,20 @@ mod tests { .expect("delete outcome lock poisoned") = outcome; } + fn set_stop_outcome(&self, outcome: ControlledLifecycleOutcome) { + *self + .stop_outcome + .lock() + .expect("stop outcome lock poisoned") = outcome; + } + + fn set_resume_outcome(&self, outcome: ControlledLifecycleOutcome) { + *self + .resume_outcome + .lock() + .expect("resume outcome lock poisoned") = outcome; + } + fn set_get_outcome(&self, outcome: ControlledGetOutcome) { *self.get_outcome.lock().expect("get outcome lock poisoned") = outcome; } @@ -3541,6 +4243,14 @@ mod tests { self.delete_calls.load(Ordering::SeqCst) } + fn stop_calls(&self) -> usize { + self.stop_calls.load(Ordering::SeqCst) + } + + fn resume_calls(&self) -> usize { + self.resume_calls.load(Ordering::SeqCst) + } + fn send_event(&self, event: WatchSandboxesEvent) { self.watch_tx .send(Ok(event)) @@ -3632,7 +4342,52 @@ mod tests { &self, _request: Request, ) -> Result, Status> { - Ok(tonic::Response::new(StopSandboxResponse {})) + self.stop_calls.fetch_add(1, Ordering::SeqCst); + self.stop_started.notify_one(); + if self.stop_blocked.load(Ordering::SeqCst) { + self.stop_release + .acquire() + .await + .expect("stop release semaphore closed") + .forget(); + } + self.stop_finished.notify_one(); + let outcome = self + .stop_outcome + .lock() + .expect("stop outcome lock poisoned") + .clone(); + match outcome { + ControlledLifecycleOutcome::Ok => Ok(tonic::Response::new(StopSandboxResponse {})), + ControlledLifecycleOutcome::Error(message) => Err(Status::internal(message)), + } + } + + async fn resume_sandbox( + &self, + _request: Request, + ) -> Result, Status> { + self.resume_calls.fetch_add(1, Ordering::SeqCst); + self.resume_started.notify_one(); + if self.resume_blocked.load(Ordering::SeqCst) { + self.resume_release + .acquire() + .await + .expect("resume release semaphore closed") + .forget(); + } + self.resume_finished.notify_one(); + let outcome = self + .resume_outcome + .lock() + .expect("resume outcome lock poisoned") + .clone(); + match outcome { + ControlledLifecycleOutcome::Ok => { + Ok(tonic::Response::new(ResumeSandboxResponse {})) + } + ControlledLifecycleOutcome::Error(message) => Err(Status::internal(message)), + } } async fn delete_sandbox( @@ -3704,7 +4459,7 @@ mod tests { tracing_log_bus: TracingLogBus::new(), supervisor_sessions: Arc::new(SupervisorSessionRegistry::new()), sync_lock: Arc::new(Mutex::new(())), - delete_gates: Arc::new(DeleteGateRegistry::default()), + lifecycle_gates: Arc::new(LifecycleGateRegistry::default()), gateway_listener_requirements: Vec::new(), replica_id: "test-replica".to_string(), } @@ -3992,7 +4747,7 @@ mod tests { #[test] fn delete_gate_registry_removes_stale_entries() { - let registry = DeleteGateRegistry::default(); + let registry = LifecycleGateRegistry::default(); let first = registry.gate_for("sb-1"); assert_eq!(registry.entry_count(), 1); drop(first); @@ -4422,6 +5177,13 @@ mod tests { self.0.stop_sandbox(request).await } + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> { + self.0.resume_sandbox(request).await + } + async fn delete_sandbox( &self, request: Request, @@ -4467,6 +5229,433 @@ mod tests { ); } + #[tokio::test] + async fn suspend_and_resume_follow_durable_state_machine() { + let driver = ControlledDriver::new(); + let runtime = test_runtime(driver.clone()).await; + let sandbox = sandbox_record("sb-lifecycle", "sandbox-lifecycle", SandboxPhase::Ready); + runtime.store.put_message(&sandbox).await.unwrap(); + let session = ssh_session_record("lifecycle-session", sandbox.object_id()); + runtime.store.put_message(&session).await.unwrap(); + register_test_supervisor_session(&runtime, sandbox.object_id()); + + let suspended = runtime + .suspend_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + assert_eq!(suspended.phase(), SandboxPhase::Suspended as i32); + assert_eq!(driver.stop_calls(), 1); + assert!(!runtime.supervisor_sessions.has_session(sandbox.object_id())); + assert!( + runtime + .store + .get_message::(session.object_id()) + .await + .unwrap() + .is_none(), + "suspension revokes ephemeral SSH sessions" + ); + + let suspended_again = runtime + .suspend_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + assert_eq!(suspended_again.phase(), SandboxPhase::Suspended as i32); + assert_eq!(driver.stop_calls(), 1, "stable suspension is idempotent"); + + let resuming = runtime + .resume_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + assert_eq!(resuming.phase(), SandboxPhase::Resuming as i32); + assert_eq!(driver.resume_calls(), 1); + + let resuming_again = runtime + .resume_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + assert_eq!(resuming_again.phase(), SandboxPhase::Resuming as i32); + assert_eq!( + driver.resume_calls(), + 2, + "explicit retry reissues the idempotent resume" + ); + + register_test_supervisor_session(&runtime, sandbox.object_id()); + runtime + .apply_sandbox_update(ready_driver_sandbox( + sandbox.object_id(), + sandbox.object_name(), + )) + .await + .unwrap(); + let ready = runtime + .resume_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + assert_eq!(ready.phase(), SandboxPhase::Ready as i32); + assert_eq!(driver.resume_calls(), 2, "ready resume is idempotent"); + } + + #[tokio::test] + async fn retained_suspending_transition_retries_driver_operation() { + let driver = ControlledDriver::new(); + let runtime = test_runtime(driver.clone()).await; + let sandbox = sandbox_record( + "sb-retained-suspend", + "sandbox-retained-suspend", + SandboxPhase::Suspending, + ); + runtime.store.put_message(&sandbox).await.unwrap(); + + let suspended = runtime + .suspend_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + + assert_eq!(suspended.phase(), SandboxPhase::Suspended as i32); + assert_eq!(driver.stop_calls(), 1); + } + + #[tokio::test] + async fn retained_resuming_transition_retries_driver_operation() { + let driver = ControlledDriver::new(); + let runtime = test_runtime(driver.clone()).await; + let sandbox = sandbox_record( + "sb-retained-resume", + "sandbox-retained-resume", + SandboxPhase::Resuming, + ); + runtime.store.put_message(&sandbox).await.unwrap(); + + let resuming = runtime + .resume_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + + assert_eq!(resuming.phase(), SandboxPhase::Resuming as i32); + assert_eq!(driver.resume_calls(), 1); + } + + #[tokio::test] + async fn repeated_suspend_completes_session_cleanup() { + let driver = ControlledDriver::new(); + let runtime = test_runtime(driver.clone()).await; + let sandbox = sandbox_record("sb-suspended", "sandbox-suspended", SandboxPhase::Suspended); + let session = ssh_session_record("stale-session", sandbox.object_id()); + runtime.store.put_message(&sandbox).await.unwrap(); + runtime.store.put_message(&session).await.unwrap(); + register_test_supervisor_session(&runtime, sandbox.object_id()); + + let suspended = runtime + .suspend_sandbox("default", sandbox.object_name()) + .await + .unwrap(); + + assert_eq!(suspended.phase(), SandboxPhase::Suspended as i32); + assert_eq!(driver.stop_calls(), 0); + assert!(!runtime.supervisor_sessions.has_session(sandbox.object_id())); + assert!( + runtime + .store + .get_message::(session.object_id()) + .await + .unwrap() + .is_none() + ); + } + + #[tokio::test] + async fn startup_recovery_completes_suspended_session_cleanup() { + let driver = ControlledDriver::new(); + let runtime = test_runtime(driver.clone()).await; + let suspended = + sandbox_record("sb-suspended", "sandbox-suspended", SandboxPhase::Suspended); + let suspending = sandbox_record( + "sb-suspending", + "sandbox-suspending", + SandboxPhase::Suspending, + ); + let suspended_session = ssh_session_record("suspended-session", suspended.object_id()); + let suspending_session = ssh_session_record("suspending-session", suspending.object_id()); + for sandbox in [&suspended, &suspending] { + runtime.store.put_message(sandbox).await.unwrap(); + register_test_supervisor_session(&runtime, sandbox.object_id()); + } + for session in [&suspended_session, &suspending_session] { + runtime.store.put_message(session).await.unwrap(); + } + + runtime.resume_persisted_sandboxes().await.unwrap(); + + assert_eq!(driver.stop_calls(), 1); + for (sandbox, session) in [ + (&suspended, &suspended_session), + (&suspending, &suspending_session), + ] { + let stored = runtime + .store + .get_message::(sandbox.object_id()) + .await + .unwrap() + .unwrap(); + assert_eq!(stored.phase(), SandboxPhase::Suspended as i32); + assert!(!runtime.supervisor_sessions.has_session(sandbox.object_id())); + assert!( + runtime + .store + .get_message::(session.object_id()) + .await + .unwrap() + .is_none() + ); + } + } + + #[tokio::test] + async fn request_cancellation_does_not_cancel_suspend_worker() { + let driver = ControlledDriver::new(); + driver.block_stop(); + let runtime = test_runtime(driver.clone()).await; + let sandbox = sandbox_record("sb-suspend", "sandbox-suspend", SandboxPhase::Ready); + runtime.store.put_message(&sandbox).await.unwrap(); + + let request_runtime = runtime.clone(); + let request = tokio::spawn(async move { + request_runtime + .suspend_sandbox("default", "sandbox-suspend") + .await + }); + tokio::time::timeout(Duration::from_secs(1), driver.stop_started.notified()) + .await + .expect("suspend did not reach the driver"); + + request.abort(); + assert!(request.await.unwrap_err().is_cancelled()); + driver.release_stop(); + tokio::time::timeout(Duration::from_secs(1), driver.stop_finished.notified()) + .await + .expect("detached suspend worker did not finish the driver call"); + + tokio::time::timeout(Duration::from_secs(1), async { + loop { + let stored = runtime + .store + .get_message::(sandbox.object_id()) + .await + .unwrap() + .unwrap(); + if stored.phase() == SandboxPhase::Suspended as i32 { + break; + } + tokio::task::yield_now().await; + } + }) + .await + .expect("detached suspend worker did not persist Suspended"); + assert_eq!(driver.stop_calls(), 1); + } + + #[tokio::test] + async fn request_cancellation_does_not_cancel_resume_worker() { + let driver = ControlledDriver::new(); + driver.block_resume(); + let runtime = test_runtime(driver.clone()).await; + let sandbox = sandbox_record("sb-resume", "sandbox-resume", SandboxPhase::Suspended); + runtime.store.put_message(&sandbox).await.unwrap(); + + let request_runtime = runtime.clone(); + let request = tokio::spawn(async move { + request_runtime + .resume_sandbox("default", "sandbox-resume") + .await + }); + tokio::time::timeout(Duration::from_secs(1), driver.resume_started.notified()) + .await + .expect("resume did not reach the driver"); + + request.abort(); + assert!(request.await.unwrap_err().is_cancelled()); + driver.release_resume(); + tokio::time::timeout(Duration::from_secs(1), driver.resume_finished.notified()) + .await + .expect("detached resume worker did not finish the driver call"); + + driver.release_resume(); + let resuming = tokio::time::timeout( + Duration::from_secs(1), + runtime.resume_sandbox("default", sandbox.object_name()), + ) + .await + .expect("detached resume worker did not release the lifecycle gate") + .unwrap(); + assert_eq!(resuming.phase(), SandboxPhase::Resuming as i32); + assert_eq!(driver.resume_calls(), 2); + } + + #[tokio::test] + async fn failed_suspend_reconciles_backend_that_already_stopped() { + let driver = ControlledDriver::new(); + driver.set_stop_outcome(ControlledLifecycleOutcome::Error("response lost")); + let sandbox = sandbox_record("sb-suspend", "sandbox-suspend", SandboxPhase::Ready); + let mut stopped = ready_driver_sandbox(sandbox.object_id(), sandbox.object_name()); + stopped.status = Some(make_driver_status(make_driver_condition( + "ContainerExited", + "container stopped before the response was lost", + ))); + driver.set_get_outcome(ControlledGetOutcome::Sandbox(Box::new(stopped))); + let runtime = test_runtime(driver).await; + runtime.store.put_message(&sandbox).await.unwrap(); + let session = ssh_session_record("lost-response-session", sandbox.object_id()); + runtime.store.put_message(&session).await.unwrap(); + register_test_supervisor_session(&runtime, sandbox.object_id()); + + let err = runtime + .suspend_sandbox("default", sandbox.object_name()) + .await + .unwrap_err(); + assert!(err.message().contains("response lost")); + + let stored = runtime + .store + .get_message::(sandbox.object_id()) + .await + .unwrap() + .unwrap(); + assert_eq!(stored.phase(), SandboxPhase::Suspended as i32); + assert!(!runtime.supervisor_sessions.has_session(sandbox.object_id())); + assert!( + runtime + .store + .get_message::(session.object_id()) + .await + .unwrap() + .is_none(), + "reconciled suspension revokes ephemeral SSH sessions" + ); + } + + #[tokio::test] + async fn failed_resume_reconciles_backend_that_already_started() { + let driver = ControlledDriver::new(); + driver.set_resume_outcome(ControlledLifecycleOutcome::Error("response lost")); + let sandbox = sandbox_record("sb-resume", "sandbox-resume", SandboxPhase::Suspended); + driver.set_get_outcome(ControlledGetOutcome::Sandbox(Box::new( + ready_driver_sandbox(sandbox.object_id(), sandbox.object_name()), + ))); + let runtime = test_runtime(driver).await; + runtime.store.put_message(&sandbox).await.unwrap(); + + let err = runtime + .resume_sandbox("default", sandbox.object_name()) + .await + .unwrap_err(); + assert!(err.message().contains("response lost")); + + let stored = runtime + .store + .get_message::(sandbox.object_id()) + .await + .unwrap() + .unwrap(); + assert_eq!(stored.phase(), SandboxPhase::Resuming as i32); + } + + #[tokio::test] + async fn lifecycle_operations_reject_invalid_source_phases() { + let runtime = test_runtime(Arc::new(TestDriver::default())).await; + let sandbox = sandbox_record( + "sb-provisioning", + "sandbox-provisioning", + SandboxPhase::Provisioning, + ); + runtime.store.put_message(&sandbox).await.unwrap(); + + let suspend = runtime + .suspend_sandbox("default", sandbox.object_name()) + .await + .unwrap_err(); + assert_eq!(suspend.code(), Code::FailedPrecondition); + + let resume = runtime + .resume_sandbox("default", sandbox.object_name()) + .await + .unwrap_err(); + assert_eq!(resume.code(), Code::FailedPrecondition); + } + + #[tokio::test] + async fn stale_ready_snapshot_cannot_wake_suspended_sandbox() { + let runtime = test_runtime(Arc::new(TestDriver::default())).await; + let sandbox = sandbox_record("sb-sleeping", "sandbox-sleeping", SandboxPhase::Suspended); + runtime.store.put_message(&sandbox).await.unwrap(); + register_test_supervisor_session(&runtime, sandbox.object_id()); + + runtime + .apply_sandbox_update(ready_driver_sandbox( + sandbox.object_id(), + sandbox.object_name(), + )) + .await + .unwrap(); + + let current = runtime + .store + .get_message::(sandbox.object_id()) + .await + .unwrap() + .unwrap(); + assert_eq!(current.phase(), SandboxPhase::Suspended as i32); + } + + #[tokio::test] + async fn stopped_container_snapshot_confirms_suspending_sandbox() { + let runtime = test_runtime(Arc::new(TestDriver::default())).await; + let sandbox = sandbox_record( + "sb-suspending", + "sandbox-suspending", + SandboxPhase::Suspending, + ); + runtime.store.put_message(&sandbox).await.unwrap(); + let mut stopped = ready_driver_sandbox(sandbox.object_id(), sandbox.object_name()); + stopped.status = Some(make_driver_status(make_driver_condition( + "ContainerExited", + "container stopped for suspension", + ))); + + runtime.apply_sandbox_update(stopped).await.unwrap(); + + let current = runtime + .store + .get_message::(sandbox.object_id()) + .await + .unwrap() + .unwrap(); + assert_eq!(current.phase(), SandboxPhase::Suspended as i32); + } + + #[tokio::test] + async fn stopped_container_snapshot_cannot_error_suspended_sandbox() { + let runtime = test_runtime(Arc::new(TestDriver::default())).await; + let sandbox = sandbox_record("sb-suspended", "sandbox-suspended", SandboxPhase::Suspended); + runtime.store.put_message(&sandbox).await.unwrap(); + let mut stopped = ready_driver_sandbox(sandbox.object_id(), sandbox.object_name()); + stopped.status = Some(make_driver_status(make_driver_condition( + "ContainerExited", + "container is stopped", + ))); + + runtime.apply_sandbox_update(stopped).await.unwrap(); + + let current = runtime + .store + .get_message::(sandbox.object_id()) + .await + .unwrap() + .unwrap(); + assert_eq!(current.phase(), SandboxPhase::Suspended as i32); + } + #[tokio::test] async fn begin_sandbox_delete_retries_after_stale_snapshot_conflict() { let runtime = test_runtime(Arc::new(TestDriver::default())).await; @@ -4814,7 +6003,7 @@ mod tests { let sandbox = sandbox_record("sb-1", "sandbox-a", SandboxPhase::Ready); runtime.store.put_message(&sandbox).await.unwrap(); - let delete_gate = runtime.delete_gates.gate_for(sandbox.object_id()); + let delete_gate = runtime.lifecycle_gates.gate_for(sandbox.object_id()); let first_runtime = runtime.clone(); let first = tokio::spawn(async move { first_runtime.delete_sandbox("default", "sandbox-a").await }); @@ -4878,7 +6067,7 @@ mod tests { let sandbox = sandbox_record("sb-1", "sandbox-a", SandboxPhase::Ready); runtime.store.put_message(&sandbox).await.unwrap(); - let delete_gate = runtime.delete_gates.gate_for(sandbox.object_id()); + let delete_gate = runtime.lifecycle_gates.gate_for(sandbox.object_id()); let first_runtime = runtime.clone(); let first = tokio::spawn(async move { first_runtime.delete_sandbox("default", "sandbox-a").await }); @@ -4937,7 +6126,7 @@ mod tests { // Hold the original ID's gate so the request resolves the name and // then waits before it can revalidate the durable row. - let delete_gate = runtime.delete_gates.gate_for(original.object_id()); + let delete_gate = runtime.lifecycle_gates.gate_for(original.object_id()); let delete_guard = delete_gate.lock().await; let delete_runtime = runtime.clone(); let delete = diff --git a/crates/openshell-server/src/grpc/mod.rs b/crates/openshell-server/src/grpc/mod.rs index d84ca41557..5339352c57 100644 --- a/crates/openshell-server/src/grpc/mod.rs +++ b/crates/openshell-server/src/grpc/mod.rs @@ -44,9 +44,10 @@ use openshell_core::proto::{ RefreshSandboxTokenRequest, RefreshSandboxTokenResponse, RejectDraftChunkRequest, RejectDraftChunkResponse, RelayFrame, RemoveWorkspaceMemberRequest, RemoveWorkspaceMemberResponse, ReportPolicyStatusRequest, ReportPolicyStatusResponse, - RevokeSshSessionRequest, RevokeSshSessionResponse, RotateProviderCredentialRequest, - RotateProviderCredentialResponse, SandboxResponse, ServiceEndpointResponse, ServiceStatus, - SubmitPolicyAnalysisRequest, SubmitPolicyAnalysisResponse, SupervisorMessage, TcpForwardFrame, + ResumeSandboxRequest, RevokeSshSessionRequest, RevokeSshSessionResponse, + RotateProviderCredentialRequest, RotateProviderCredentialResponse, SandboxResponse, + ServiceEndpointResponse, ServiceStatus, SubmitPolicyAnalysisRequest, + SubmitPolicyAnalysisResponse, SupervisorMessage, SuspendSandboxRequest, TcpForwardFrame, UndoDraftChunkRequest, UndoDraftChunkResponse, UpdateConfigRequest, UpdateConfigResponse, UpdateProviderProfilesRequest, UpdateProviderProfilesResponse, UpdateProviderRequest, WatchSandboxRequest, open_shell_server::OpenShell, @@ -323,6 +324,20 @@ impl OpenShell for OpenShellService { sandbox::handle_delete_sandbox(&self.state, request).await } + async fn suspend_sandbox( + &self, + request: Request, + ) -> Result, Status> { + sandbox::handle_suspend_sandbox(&self.state, request).await + } + + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> { + sandbox::handle_resume_sandbox(&self.state, request).await + } + // --- Exec --- type ExecSandboxStream = ReceiverStream>; diff --git a/crates/openshell-server/src/grpc/sandbox.rs b/crates/openshell-server/src/grpc/sandbox.rs index 4925c9eaea..a02f2a5091 100644 --- a/crates/openshell-server/src/grpc/sandbox.rs +++ b/crates/openshell-server/src/grpc/sandbox.rs @@ -22,9 +22,10 @@ use openshell_core::proto::{ DetachSandboxProviderRequest, DetachSandboxProviderResponse, ExecSandboxEvent, ExecSandboxExit, ExecSandboxInput, ExecSandboxRequest, ExecSandboxStderr, ExecSandboxStdout, GetSandboxRequest, ListSandboxProvidersRequest, ListSandboxProvidersResponse, ListSandboxesRequest, - ListSandboxesResponse, Provider, RevokeSshSessionRequest, RevokeSshSessionResponse, - SandboxResponse, SandboxStreamEvent, SshRelayTarget, TcpForwardFrame, TcpForwardInit, - TcpRelayTarget, WatchSandboxRequest, relay_open, tcp_forward_init, + ListSandboxesResponse, Provider, ResumeSandboxRequest, RevokeSshSessionRequest, + RevokeSshSessionResponse, SandboxResponse, SandboxStreamEvent, SshRelayTarget, + SuspendSandboxRequest, TcpForwardFrame, TcpForwardInit, TcpRelayTarget, WatchSandboxRequest, + relay_open, tcp_forward_init, }; use openshell_core::proto::{Sandbox, SandboxPhase, SandboxTemplate, SshSession}; use openshell_core::telemetry::{ @@ -740,6 +741,94 @@ async fn handle_delete_sandbox_inner( })) } +pub(super) async fn handle_suspend_sandbox( + state: &Arc, + request: Request, +) -> Result, Status> { + let result = handle_suspend_sandbox_inner(state, request).await; + openshell_core::telemetry::emit_lifecycle( + LifecycleResource::Sandbox, + LifecycleOperation::Suspend, + if result.is_ok() { + TelemetryOutcome::Success + } else { + TelemetryOutcome::Failure + }, + ); + result +} + +async fn handle_suspend_sandbox_inner( + state: &Arc, + request: Request, +) -> Result, Status> { + let principal = super::extract_principal(&request)?; + let req = request.into_inner(); + if req.name.is_empty() { + return Err(Status::invalid_argument("name is required")); + } + let authz = authorize_workspace( + &state.store, + &state.admin_role, + &principal, + &req.workspace, + MinWorkspaceRole::User, + ) + .await?; + let workspace = super::workspace::resolve_workspace(state.store.as_ref(), &authz.workspace) + .await? + .name; + let sandbox = state.compute.suspend_sandbox(&workspace, &req.name).await?; + info!(sandbox_name = %req.name, "SuspendSandbox request completed successfully"); + Ok(Response::new(SandboxResponse { + sandbox: Some(sandbox), + })) +} + +pub(super) async fn handle_resume_sandbox( + state: &Arc, + request: Request, +) -> Result, Status> { + let result = handle_resume_sandbox_inner(state, request).await; + openshell_core::telemetry::emit_lifecycle( + LifecycleResource::Sandbox, + LifecycleOperation::Resume, + if result.is_ok() { + TelemetryOutcome::Success + } else { + TelemetryOutcome::Failure + }, + ); + result +} + +async fn handle_resume_sandbox_inner( + state: &Arc, + request: Request, +) -> Result, Status> { + let principal = super::extract_principal(&request)?; + let req = request.into_inner(); + if req.name.is_empty() { + return Err(Status::invalid_argument("name is required")); + } + let authz = authorize_workspace( + &state.store, + &state.admin_role, + &principal, + &req.workspace, + MinWorkspaceRole::User, + ) + .await?; + let workspace = super::workspace::resolve_workspace(state.store.as_ref(), &authz.workspace) + .await? + .name; + let sandbox = state.compute.resume_sandbox(&workspace, &req.name).await?; + info!(sandbox_name = %req.name, "ResumeSandbox request completed successfully"); + Ok(Response::new(SandboxResponse { + sandbox: Some(sandbox), + })) +} + async fn sandbox_by_name( state: &Arc, workspace: &str, @@ -2702,7 +2791,7 @@ mod tests { .await }); tokio::time::timeout(std::time::Duration::from_secs(5), async { - while state.compute.delete_gate_entry_count() == 0 { + while state.compute.lifecycle_gate_entry_count() == 0 { tokio::time::sleep(std::time::Duration::from_millis(10)).await; } }) @@ -4345,6 +4434,31 @@ mod tests { Code::PermissionDenied, "handle_delete_sandbox should reject non-members with PermissionDenied" ); + + for result in [ + handle_suspend_sandbox( + &state, + non_member_request(SuspendSandboxRequest { + workspace: "no-such-ws".into(), + name: "any".into(), + }), + ) + .await, + handle_resume_sandbox( + &state, + non_member_request(ResumeSandboxRequest { + workspace: "no-such-ws".into(), + name: "any".into(), + }), + ) + .await, + ] { + assert_eq!( + result.unwrap_err().code(), + Code::PermissionDenied, + "lifecycle handlers should reject non-members" + ); + } } /// ID-based data-plane handlers must return `NOT_FOUND` — never diff --git a/crates/openshell-server/src/supervisor_session.rs b/crates/openshell-server/src/supervisor_session.rs index e6b8085151..11a1eac540 100644 --- a/crates/openshell-server/src/supervisor_session.rs +++ b/crates/openshell-server/src/supervisor_session.rs @@ -141,6 +141,20 @@ impl SupervisorSessionRegistry { self.sessions.lock().unwrap().remove(sandbox_id); } + /// Disconnect the current supervisor session for a sandbox. + /// + /// Lifecycle suspension uses this to ensure a later resume must establish + /// a fresh session before the sandbox can return to Ready. + pub fn disconnect(&self, sandbox_id: &str) -> bool { + let session = self.sessions.lock().unwrap().remove(sandbox_id); + if let Some(session) = session { + let _ = session.shutdown.send(()); + true + } else { + false + } + } + /// Remove the session only if its `session_id` matches the one we are /// cleaning up. Returns `true` if the entry was removed. /// diff --git a/crates/openshell-server/src/test_support.rs b/crates/openshell-server/src/test_support.rs index d1aa10da11..43c7444178 100644 --- a/crates/openshell-server/src/test_support.rs +++ b/crates/openshell-server/src/test_support.rs @@ -11,9 +11,10 @@ use openshell_core::proto::compute::v1::{ DriverSandbox, GatewayListenerRequirement, GetCapabilitiesRequest, GetCapabilitiesResponse, GetGatewayListenerRequirementsRequest, GetGatewayListenerRequirementsResponse, GetSandboxRequest, GetSandboxResponse, ListSandboxesRequest, ListSandboxesResponse, - StopSandboxRequest, StopSandboxResponse, ValidateSandboxCreateRequest, - ValidateSandboxCreateResponse, WatchSandboxesEvent, WatchSandboxesRequest, - compute_driver_server::ComputeDriver, gateway_listener_requirement::Selector, + ResumeSandboxRequest, ResumeSandboxResponse, StopSandboxRequest, StopSandboxResponse, + ValidateSandboxCreateRequest, ValidateSandboxCreateResponse, WatchSandboxesEvent, + WatchSandboxesRequest, compute_driver_server::ComputeDriver, + gateway_listener_requirement::Selector, }; use std::collections::HashMap; #[cfg(unix)] @@ -51,6 +52,10 @@ pub enum FakeComputeDriverCall { sandbox_id: String, sandbox_name: String, }, + ResumeSandbox { + sandbox_id: String, + sandbox_name: String, + }, DeleteSandbox { sandbox_id: String, sandbox_name: String, @@ -344,6 +349,21 @@ impl ComputeDriver for FakeComputeDriver { Ok(Response::new(StopSandboxResponse {})) } + async fn resume_sandbox( + &self, + request: Request, + ) -> Result, Status> { + self.record_traceparent(request.metadata()); + let request = request.into_inner(); + self.with_state(|state| { + state.calls.push(FakeComputeDriverCall::ResumeSandbox { + sandbox_id: request.sandbox_id, + sandbox_name: request.sandbox_name, + }); + }); + Ok(Response::new(ResumeSandboxResponse {})) + } + async fn delete_sandbox( &self, request: Request, diff --git a/crates/openshell-server/tests/common/mod.rs b/crates/openshell-server/tests/common/mod.rs index cfd7faa3d6..7bdb7b759c 100644 --- a/crates/openshell-server/tests/common/mod.rs +++ b/crates/openshell-server/tests/common/mod.rs @@ -83,6 +83,20 @@ impl OpenShell for TestOpenShell { Ok(Response::new(SandboxResponse::default())) } + async fn suspend_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + + async fn resume_sandbox( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + async fn get_sandbox( &self, _request: tonic::Request, diff --git a/crates/openshell-server/tests/supervisor_relay_integration.rs b/crates/openshell-server/tests/supervisor_relay_integration.rs index be1af8f48c..4809433f6b 100644 --- a/crates/openshell-server/tests/supervisor_relay_integration.rs +++ b/crates/openshell-server/tests/supervisor_relay_integration.rs @@ -130,6 +130,18 @@ impl OpenShell for RelayGateway { ) -> Result, Status> { Err(Status::unimplemented("unused")) } + async fn suspend_sandbox( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + async fn resume_sandbox( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn get_sandbox( &self, _: tonic::Request, diff --git a/docs/reference/sandbox-compute-drivers.mdx b/docs/reference/sandbox-compute-drivers.mdx index 2132f3360e..ae684943fd 100644 --- a/docs/reference/sandbox-compute-drivers.mdx +++ b/docs/reference/sandbox-compute-drivers.mdx @@ -8,10 +8,16 @@ keywords: "Generative AI, Cybersecurity, AI Agents, Sandboxing, Docker, Podman, position: 4 --- -The gateway's configured compute driver determines how OpenShell creates each sandbox. The CLI workflow stays the same across drivers: you create, connect to, inspect, and delete sandboxes through the gateway API. +The gateway's configured compute driver determines how OpenShell creates each sandbox. The CLI workflow stays the same across drivers: you create, connect to, inspect, suspend, resume, and delete sandboxes through the gateway API. Every compute driver runs the OpenShell supervisor inside the sandbox workload. The supervisor launches the agent process, applies policy, routes egress through the proxy, injects configured credentials, and maintains the gateway session. +Suspend stops compute but retains the sandbox record and the driver's +persistent workspace boundary. Resume reactivates the same driver resource. +Delete remains independent and removes compute plus driver-owned persistent +state. While a sandbox is suspended, gateway access paths and exposed services +remain unavailable. + ## Configure a Compute Driver Configure the compute driver on the gateway. Current releases accept one driver per gateway. Set `compute_drivers` in the gateway TOML file: @@ -127,6 +133,11 @@ For maintainer-level implementation details, refer to the [Docker driver README] Select Docker with `compute_drivers = ["docker"]` in `[openshell.gateway]`. Configure Docker driver values such as `socket_path`, `grpc_endpoint`, `network_name`, `supervisor_bin`, `supervisor_image`, `image_pull_policy`, `ssh_socket_path`, `sandbox_pids_limit`, and `guest_tls_*` in `[openshell.drivers.docker]`. When `socket_path` is unset, the driver uses the same responsive local socket selected by auto-detection. An explicitly selected Docker driver falls back to `/var/run/docker.sock` when no candidate responds. +Suspend stops the existing Docker container without removing its writable +layer or attached volumes. Resume starts that same container. A durably +suspended container stays stopped across gateway restart, and delete remains +responsible for removing it. + For GPU-backed Docker sandboxes, configure Docker CDI before starting the gateway so OpenShell can detect the daemon capability. ### Docker Driver Config Mounts @@ -195,6 +206,10 @@ Select Podman with `compute_drivers = ["podman"]` in `[openshell.gateway]`. Conf Podman sandboxes default to a 45-second graceful stop window before Podman escalates from `SIGTERM` to `SIGKILL`. Set `stop_timeout_secs` in gateway config, or `OPENSHELL_STOP_TIMEOUT` for the standalone driver, when a local runtime needs a different teardown window. +Suspend stops the existing Podman container while retaining its named workspace +volume and driver-owned secrets. Resume starts the same container. Delete is +the operation that removes the container and named volume. + For proxy-required networks, the Podman driver also accepts the corporate egress proxy keys `https_proxy`, `no_proxy`, `proxy_auth_file`, `proxy_auth_allow_insecure`, and `proxy_connect_by_hostname`. The supervisor chains policy-approved TLS tunnels through the proxy with HTTP CONNECT instead of dialing destinations directly. See the [Gateway Configuration File](./gateway-config) reference for the full contract, including the cleartext-credential acknowledgement and the validated-IP CONNECT behavior. On macOS with `podman machine`, the driver uses gvproxy's host-loopback IP, `192.168.127.254`, for sandbox host aliases by default. Set `host_gateway_ip` only when your Podman machine uses a non-standard host-loopback address. On Linux, an empty `host_gateway_ip` keeps Podman's `host-gateway` resolver behavior. Direct local callbacks from rootless Podman require Podman to report the pasta network helper. Slirp4netns, other helpers, and Podman versions that do not report their helper require an explicitly remote `grpc_endpoint`; otherwise the gateway fails startup rather than leaving sandbox callbacks unreachable. Rootful Podman continues to use the configured network's bridge gateway address. @@ -267,6 +282,10 @@ VM sandbox creation follows the same progress model as Kubernetes-backed sandbox On gateway restart, the gateway starts a fresh VM driver process. The driver scans its state directory for accepted sandbox launch records, restarts those VMs, and reuses each sandbox's existing `overlay.ext4` so files written inside the sandbox remain available after the supervisor reconnects. +Suspended VM state directories contain a marker that prevents startup from +launching the VM. The driver retains `sandbox.pb`, `overlay.ext4`, and extension +state, then removes the marker and restores the same overlay on resume. + For maintainer-level implementation details, refer to the [VM driver README](https://github.com/NVIDIA/OpenShell/blob/main/crates/openshell-driver-vm/README.md). ### Enable the VM Driver @@ -356,6 +375,11 @@ process/binary identity through `/proc/`. The Kubernetes driver creates namespaced `agents.x-k8s.io` `Sandbox` resources from the Kubernetes SIG Apps [agent-sandbox](https://github.com/kubernetes-sigs/agent-sandbox) project. It detects the served Sandbox API at runtime, caches the selected API version for the gateway process, and uses `v1beta1` when available before falling back to `v1alpha1`, so supported Agent Sandbox installations work without version-specific operator configuration. The Agent Sandbox controller turns those resources into sandbox pods and related storage. +Suspend patches the existing resource rather than deleting it. For `v1beta1`, +the driver sets `spec.operatingMode` to `Suspended` or `Running`. For +`v1alpha1`, it sets `spec.replicas` to `0` or `1`. The Sandbox resource and its +workspace PVC keep their identity across both operations. + If Agent Sandbox is upgraded in place, restart the OpenShell gateway after the controller and CRD rollout completes so the gateway can detect the served API versions again. diff --git a/docs/sandboxes/manage-sandboxes.mdx b/docs/sandboxes/manage-sandboxes.mdx index bc408c4ecd..0218fb5cfb 100644 --- a/docs/sandboxes/manage-sandboxes.mdx +++ b/docs/sandboxes/manage-sandboxes.mdx @@ -436,6 +436,26 @@ back to an unfiltered upload and prints a warning. Pass `--no-git-ignore` to opt into unfiltered uploads explicitly, upload a path outside the Git work tree, or force-add the intended files if they should remain Git-aware. +## Suspend and Resume Sandboxes + +Suspend compute when you want to retain a sandbox and its persistent workspace +without keeping its container, pod, or VM running: + +```shell +openshell sandbox suspend my-sandbox +openshell sandbox resume my-sandbox +``` + +The name is optional and defaults to the last-used sandbox. Suspend stops local +background forwards and waits for the `Suspended` phase. Resume waits until the +same sandbox returns to `Ready`. While suspended, you cannot connect, execute +commands, transfer files, forward ports, or reach exposed services. Policies, +provider attachments, settings, service definitions, and persistent workspace +data remain associated with the sandbox. + +Suspend and resume are idempotent. Delete a suspended sandbox normally when you +no longer need its retained state. + ## Delete Sandboxes Deleting a sandbox stops all processes, releases resources, and purges injected credentials. @@ -452,6 +472,9 @@ Every sandbox moves through a defined set of phases: | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Provisioning | The runtime is setting up the sandbox environment, or the gateway is waiting for the sandbox supervisor to establish its authenticated control session. | | Ready | The sandbox is running and its supervisor control session is connected. You can connect, execute commands, sync files, and view logs. | +| Suspending | The gateway accepted a suspend request and is stopping compute while retaining persistent state. | +| Suspended | Compute is stopped and access is unavailable. The sandbox record and driver-owned persistent workspace remain. | +| Resuming | Compute is restarting. The sandbox becomes usable only after a fresh supervisor session connects. | | Error | Something went wrong during provisioning or execution. Check logs with `openshell logs` for details. | | Deleting | The sandbox is being torn down. The system releases resources and purges credentials. | diff --git a/e2e/rust/tests/sandbox_lifecycle.rs b/e2e/rust/tests/sandbox_lifecycle.rs index 4b832411fe..a7de33d656 100644 --- a/e2e/rust/tests/sandbox_lifecycle.rs +++ b/e2e/rust/tests/sandbox_lifecycle.rs @@ -8,6 +8,7 @@ use std::time::Duration; use openshell_e2e::harness::binary::{openshell_cmd, openshell_tty_cmd}; use openshell_e2e::harness::output::{extract_field, strip_ansi}; +use openshell_e2e::harness::sandbox::SandboxGuard; use tokio::time::{Instant, sleep}; const SANDBOX_PRESENCE_TIMEOUT: Duration = Duration::from_secs(30); @@ -105,6 +106,118 @@ async fn delete_sandbox(name: &str) { let _ = cmd.status().await; } +async fn run_sandbox_lifecycle_command(operation: &str, name: &str) -> String { + let mut cmd = openshell_cmd(); + cmd.args(["sandbox", operation, name]) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); + + let output = cmd + .output() + .await + .unwrap_or_else(|error| panic!("spawn openshell sandbox {operation}: {error}")); + let combined = normalize_output(&format!( + "{}{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr), + )); + assert!( + output.status.success(), + "sandbox {operation} should succeed (exit {:?}):\n{combined}", + output.status.code(), + ); + combined +} + +#[tokio::test] +async fn sandbox_suspend_resume_preserves_workspace() { + const SENTINEL: &str = "openshell-suspend-resume-sentinel"; + const SENTINEL_PATH: &str = "/sandbox/.openshell-suspend-resume-e2e"; + let write_sentinel = format!("printf '%s\\n' '{SENTINEL}' > '{SENTINEL_PATH}'"); + + let mut sandbox = SandboxGuard::create(&["--", "sh", "-lc", &write_sentinel]) + .await + .expect("sandbox create should write the workspace sentinel"); + + let suspend_output = run_sandbox_lifecycle_command("suspend", &sandbox.name).await; + assert!( + suspend_output.contains("Suspended sandbox"), + "expected suspend confirmation in:\n{suspend_output}", + ); + + let mut exec_cmd = openshell_cmd(); + exec_cmd + .args([ + "sandbox", + "exec", + "--name", + &sandbox.name, + "--no-tty", + "--", + "cat", + SENTINEL_PATH, + ]) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); + let suspended_exec = exec_cmd + .output() + .await + .expect("spawn openshell sandbox exec while suspended"); + assert!( + !suspended_exec.status.success(), + "sandbox exec should fail while suspended" + ); + + let resume_output = run_sandbox_lifecycle_command("resume", &sandbox.name).await; + assert!( + resume_output.contains("Resumed sandbox"), + "expected resume confirmation in:\n{resume_output}", + ); + + let sentinel = sandbox + .exec(&["cat", SENTINEL_PATH]) + .await + .expect("sandbox exec should succeed after resume"); + assert!( + sentinel.lines().any(|line| line.trim() == SENTINEL), + "workspace sentinel should survive suspend and resume:\n{sentinel}", + ); + + sandbox.cleanup().await; +} + +#[tokio::test] +async fn sandbox_can_be_deleted_while_suspended() { + let mut sandbox = SandboxGuard::create(&["--", "true"]) + .await + .expect("sandbox create should succeed"); + + let suspend_output = run_sandbox_lifecycle_command("suspend", &sandbox.name).await; + assert!( + suspend_output.contains("Suspended sandbox"), + "expected suspend confirmation in:\n{suspend_output}", + ); + + let delete_output = run_sandbox_lifecycle_command("delete", &sandbox.name).await; + assert!( + delete_output.contains("Deleted sandbox"), + "expected delete confirmation in:\n{delete_output}", + ); + + if let Err(last_sandbox_list) = assert_sandbox_presence_eventually(&sandbox.name, false).await { + sandbox.cleanup().await; + panic!( + "suspended sandbox {} should be deleted without resuming after \ + {SANDBOX_PRESENCE_TIMEOUT:?}; last observed sandbox list: {last_sandbox_list:?}", + sandbox.name, + ); + } + + // Mark the guard cleaned up. Its idempotent delete is harmless now that + // the lifecycle operation above has removed the sandbox. + sandbox.cleanup().await; +} + #[tokio::test] async fn sandbox_create_keeps_sandbox_after_tty_command_by_default() { let mut cmd = openshell_tty_cmd(&["sandbox", "create", "--", "echo", "OK"]); diff --git a/proto/compute_driver.proto b/proto/compute_driver.proto index e3f18af19f..e916c1d4df 100644 --- a/proto/compute_driver.proto +++ b/proto/compute_driver.proto @@ -40,9 +40,12 @@ service ComputeDriver { // Provision platform resources for a sandbox. rpc CreateSandbox(CreateSandboxRequest) returns (CreateSandboxResponse); - // Stop platform resources for a sandbox without deleting its record. + // Idempotently stop platform resources without deleting persistent state. rpc StopSandbox(StopSandboxRequest) returns (StopSandboxResponse); + // Idempotently resume platform resources for a stopped sandbox. + rpc ResumeSandbox(ResumeSandboxRequest) returns (ResumeSandboxResponse); + // Tear down platform resources for a sandbox. rpc DeleteSandbox(DeleteSandboxRequest) returns (DeleteSandboxResponse); @@ -286,6 +289,15 @@ message StopSandboxRequest { message StopSandboxResponse {} +message ResumeSandboxRequest { + // Stable sandbox ID stored by the gateway. + string sandbox_id = 1; + // Compute-runtime name used by the driver. + string sandbox_name = 2; +} + +message ResumeSandboxResponse {} + message DeleteSandboxRequest { // Stable sandbox ID stored by the gateway. string sandbox_id = 1; diff --git a/proto/openshell.proto b/proto/openshell.proto index 9f2fdf9006..a6750f1a5e 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -108,6 +108,24 @@ service OpenShell { }; } + // Suspend a sandbox while retaining its persistent state. + rpc SuspendSandbox(SuspendSandboxRequest) returns (SandboxResponse) { + option (openshell.options.v1.authorization) = { + auth_mode: "bearer" + scope: "sandbox:write" + workspace_role: "user" + }; + } + + // Resume a previously suspended sandbox. + rpc ResumeSandbox(ResumeSandboxRequest) returns (SandboxResponse) { + option (openshell.options.v1.authorization) = { + auth_mode: "bearer" + scope: "sandbox:write" + workspace_role: "user" + }; + } + // Create a short-lived SSH session for a sandbox. rpc CreateSshSession(CreateSshSessionRequest) returns (CreateSshSessionResponse) { option (openshell.options.v1.authorization) = { @@ -879,6 +897,9 @@ enum SandboxPhase { SANDBOX_PHASE_ERROR = 3; SANDBOX_PHASE_DELETING = 4; SANDBOX_PHASE_UNKNOWN = 5; + SANDBOX_PHASE_SUSPENDING = 6; + SANDBOX_PHASE_SUSPENDED = 7; + SANDBOX_PHASE_RESUMING = 8; } // Public platform event exposed on the sandbox watch stream. @@ -976,6 +997,22 @@ message DeleteSandboxRequest { string workspace = 2; } +// Suspend sandbox request. +message SuspendSandboxRequest { + // Sandbox name (canonical lookup key). + string name = 1; + // Workspace scope. Empty defaults to "default". + string workspace = 2; +} + +// Resume sandbox request. +message ResumeSandboxRequest { + // Sandbox name (canonical lookup key). + string name = 1; + // Workspace scope. Empty defaults to "default". + string workspace = 2; +} + // Sandbox response. message SandboxResponse { Sandbox sandbox = 1; diff --git a/python/openshell/sandbox.py b/python/openshell/sandbox.py index b62a9c8855..d976014b99 100644 --- a/python/openshell/sandbox.py +++ b/python/openshell/sandbox.py @@ -250,6 +250,16 @@ def exec_python( def delete(self) -> bool: return self._client.delete(self.sandbox.name, workspace=self._workspace) + def suspend(self) -> SandboxRef: + self.sandbox = self._client.suspend( + self.sandbox.name, workspace=self._workspace + ) + return self.sandbox + + def resume(self) -> SandboxRef: + self.sandbox = self._client.resume(self.sandbox.name, workspace=self._workspace) + return self.sandbox + class SandboxClient: """gRPC client for sandbox CRUD and command execution.""" @@ -546,6 +556,20 @@ def delete(self, sandbox_name: str, *, workspace: str) -> bool: ) return bool(response.deleted) + def suspend(self, sandbox_name: str, *, workspace: str) -> SandboxRef: + response = self._stub.SuspendSandbox( + openshell_pb2.SuspendSandboxRequest(name=sandbox_name, workspace=workspace), + timeout=self._timeout, + ) + return _sandbox_ref(response.sandbox) + + def resume(self, sandbox_name: str, *, workspace: str) -> SandboxRef: + response = self._stub.ResumeSandbox( + openshell_pb2.ResumeSandboxRequest(name=sandbox_name, workspace=workspace), + timeout=self._timeout, + ) + return _sandbox_ref(response.sandbox) + def wait_deleted( self, sandbox_name: str, *, workspace: str, timeout_seconds: float = 60.0 ) -> None: @@ -565,16 +589,46 @@ def wait_deleted( def wait_ready( self, sandbox_name: str, *, workspace: str, timeout_seconds: float = 300.0 + ) -> SandboxRef: + return self._wait_for_phase( + sandbox_name, + workspace=workspace, + target_phase=openshell_pb2.SANDBOX_PHASE_READY, + target_name="ready", + timeout_seconds=timeout_seconds, + ) + + def wait_suspended( + self, sandbox_name: str, *, workspace: str, timeout_seconds: float = 300.0 + ) -> SandboxRef: + return self._wait_for_phase( + sandbox_name, + workspace=workspace, + target_phase=openshell_pb2.SANDBOX_PHASE_SUSPENDED, + target_name="suspended", + timeout_seconds=timeout_seconds, + ) + + def _wait_for_phase( + self, + sandbox_name: str, + *, + workspace: str, + target_phase: int, + target_name: str, + timeout_seconds: float, ) -> SandboxRef: deadline = time.time() + timeout_seconds while time.time() < deadline: sandbox = self.get(sandbox_name, workspace=workspace) - if sandbox.status.phase == openshell_pb2.SANDBOX_PHASE_READY: + if sandbox.status.phase == target_phase: return sandbox if sandbox.status.phase == openshell_pb2.SANDBOX_PHASE_ERROR: raise SandboxError(f"sandbox {sandbox_name} entered error phase") time.sleep(1) - raise SandboxError(f"sandbox {sandbox_name} was not ready within timeout") + raise SandboxError( + f"sandbox {sandbox_name} was not {target_name} within timeout" + ) def exec_stream( self, diff --git a/python/openshell/sandbox_test.py b/python/openshell/sandbox_test.py index f1cb06148c..51a6bcb1c5 100644 --- a/python/openshell/sandbox_test.py +++ b/python/openshell/sandbox_test.py @@ -1482,6 +1482,8 @@ def __init__(self, listed: list[openshell_pb2.Sandbox] | None = None) -> None: self.list_request: openshell_pb2.ListSandboxesRequest | None = None self.get_request: openshell_pb2.GetSandboxRequest | None = None self.delete_request: openshell_pb2.DeleteSandboxRequest | None = None + self.suspend_request: openshell_pb2.SuspendSandboxRequest | None = None + self.resume_request: openshell_pb2.ResumeSandboxRequest | None = None self._listed = listed or [] def GetSandbox( @@ -1506,6 +1508,38 @@ def DeleteSandbox( _ = timeout return SimpleNamespace(deleted=True) + def SuspendSandbox( + self, + request: openshell_pb2.SuspendSandboxRequest, + timeout: float | None = None, + ) -> Any: + self.suspend_request = request + _ = timeout + return SimpleNamespace( + sandbox=_make_sandbox_proto( + "sandbox-1", + request.name, + phase=openshell_pb2.SANDBOX_PHASE_SUSPENDED, + workspace=request.workspace, + ) + ) + + def ResumeSandbox( + self, + request: openshell_pb2.ResumeSandboxRequest, + timeout: float | None = None, + ) -> Any: + self.resume_request = request + _ = timeout + return SimpleNamespace( + sandbox=_make_sandbox_proto( + "sandbox-1", + request.name, + phase=openshell_pb2.SANDBOX_PHASE_RESUMING, + workspace=request.workspace, + ) + ) + def CreateSandbox( self, request: openshell_pb2.CreateSandboxRequest, @@ -1580,6 +1614,23 @@ def test_create_forwards_name_and_labels() -> None: assert dict(ref.labels) == {"aiq": "deep-research"} +def test_suspend_and_resume_forward_workspace_and_return_phase() -> None: + stub = _FakeSandboxStub() + client = _client_with_fake_stub(stub) + + suspended = client.suspend("job-1", workspace="team-a") + assert stub.suspend_request is not None + assert stub.suspend_request.name == "job-1" + assert stub.suspend_request.workspace == "team-a" + assert suspended.phase == openshell_pb2.SANDBOX_PHASE_SUSPENDED + + resuming = client.resume("job-1", workspace="team-a") + assert stub.resume_request is not None + assert stub.resume_request.name == "job-1" + assert stub.resume_request.workspace == "team-a" + assert resuming.phase == openshell_pb2.SANDBOX_PHASE_RESUMING + + def test_create_without_args_sends_empty_metadata() -> None: stub = _FakeSandboxStub() client = _client_with_fake_stub(stub) diff --git a/sdk/go/openshell/v1/internal/converter/sandbox.go b/sdk/go/openshell/v1/internal/converter/sandbox.go index b522454b83..8838480ed9 100644 --- a/sdk/go/openshell/v1/internal/converter/sandbox.go +++ b/sdk/go/openshell/v1/internal/converter/sandbox.go @@ -110,6 +110,12 @@ func SandboxPhaseFromProto(phase pb.SandboxPhase) types.SandboxPhase { return types.SandboxDeleting case pb.SandboxPhase_SANDBOX_PHASE_UNKNOWN: return types.SandboxUnknown + case pb.SandboxPhase_SANDBOX_PHASE_SUSPENDING: + return types.SandboxSuspending + case pb.SandboxPhase_SANDBOX_PHASE_SUSPENDED: + return types.SandboxSuspended + case pb.SandboxPhase_SANDBOX_PHASE_RESUMING: + return types.SandboxResuming default: return types.SandboxUnknown } @@ -128,6 +134,12 @@ func SandboxPhaseToProto(phase types.SandboxPhase) pb.SandboxPhase { return pb.SandboxPhase_SANDBOX_PHASE_DELETING case types.SandboxUnknown: return pb.SandboxPhase_SANDBOX_PHASE_UNKNOWN + case types.SandboxSuspending: + return pb.SandboxPhase_SANDBOX_PHASE_SUSPENDING + case types.SandboxSuspended: + return pb.SandboxPhase_SANDBOX_PHASE_SUSPENDED + case types.SandboxResuming: + return pb.SandboxPhase_SANDBOX_PHASE_RESUMING default: return pb.SandboxPhase_SANDBOX_PHASE_UNKNOWN } diff --git a/sdk/go/openshell/v1/internal/converter/sandbox_test.go b/sdk/go/openshell/v1/internal/converter/sandbox_test.go index f3c41650ea..9b9cf3abf0 100644 --- a/sdk/go/openshell/v1/internal/converter/sandbox_test.go +++ b/sdk/go/openshell/v1/internal/converter/sandbox_test.go @@ -142,6 +142,9 @@ func TestSandboxPhaseFromProto(t *testing.T) { {pb.SandboxPhase_SANDBOX_PHASE_ERROR, v1.SandboxError}, {pb.SandboxPhase_SANDBOX_PHASE_DELETING, v1.SandboxDeleting}, {pb.SandboxPhase_SANDBOX_PHASE_UNKNOWN, v1.SandboxUnknown}, + {pb.SandboxPhase_SANDBOX_PHASE_SUSPENDING, v1.SandboxSuspending}, + {pb.SandboxPhase_SANDBOX_PHASE_SUSPENDED, v1.SandboxSuspended}, + {pb.SandboxPhase_SANDBOX_PHASE_RESUMING, v1.SandboxResuming}, {pb.SandboxPhase_SANDBOX_PHASE_UNSPECIFIED, v1.SandboxUnknown}, {pb.SandboxPhase(999), v1.SandboxUnknown}, } @@ -161,6 +164,9 @@ func TestSandboxPhaseToProto(t *testing.T) { {v1.SandboxError, pb.SandboxPhase_SANDBOX_PHASE_ERROR}, {v1.SandboxDeleting, pb.SandboxPhase_SANDBOX_PHASE_DELETING}, {v1.SandboxUnknown, pb.SandboxPhase_SANDBOX_PHASE_UNKNOWN}, + {v1.SandboxSuspending, pb.SandboxPhase_SANDBOX_PHASE_SUSPENDING}, + {v1.SandboxSuspended, pb.SandboxPhase_SANDBOX_PHASE_SUSPENDED}, + {v1.SandboxResuming, pb.SandboxPhase_SANDBOX_PHASE_RESUMING}, {v1.SandboxPhase("bogus"), pb.SandboxPhase_SANDBOX_PHASE_UNKNOWN}, } diff --git a/sdk/go/openshell/v1/sandbox.go b/sdk/go/openshell/v1/sandbox.go index 2dfc6ba8ac..9de8959907 100644 --- a/sdk/go/openshell/v1/sandbox.go +++ b/sdk/go/openshell/v1/sandbox.go @@ -56,11 +56,14 @@ type SandboxInterface interface { Create(ctx context.Context, workspace, name string, spec *SandboxSpec, labels map[string]string) (*Sandbox, error) Get(ctx context.Context, workspace, name string) (*Sandbox, error) List(ctx context.Context, workspace string, opts ...ListOptions) ([]*Sandbox, error) + Suspend(ctx context.Context, workspace, name string) (*Sandbox, error) + Resume(ctx context.Context, workspace, name string) (*Sandbox, error) Delete(ctx context.Context, workspace, name string) error AttachProvider(ctx context.Context, workspace, sandboxName, providerName string, expectedResourceVersion uint64) (*AttachProviderResult, error) DetachProvider(ctx context.Context, workspace, sandboxName, providerName string, expectedResourceVersion uint64) (*DetachProviderResult, error) ListProviders(ctx context.Context, workspace, sandboxName string) ([]*Provider, error) WaitReady(ctx context.Context, workspace, name string, opts ...WaitOptions) (*Sandbox, error) + WaitSuspended(ctx context.Context, workspace, name string, opts ...WaitOptions) (*Sandbox, error) Watch(ctx context.Context, workspace, name string, opts ...WatchOptions) (WatchInterface[*Sandbox], error) // GetLogs retrieves log entries for a sandbox. The sandbox is resolved // by name (an internal Get call translates name to ID). Use diff --git a/sdk/go/openshell/v1/sandbox_client.go b/sdk/go/openshell/v1/sandbox_client.go index 6c38db7811..103bb764ef 100644 --- a/sdk/go/openshell/v1/sandbox_client.go +++ b/sdk/go/openshell/v1/sandbox_client.go @@ -91,6 +91,28 @@ func (s *sandboxClient) Delete(ctx context.Context, workspace, name string) erro return nil } +func (s *sandboxClient) Suspend(ctx context.Context, workspace, name string) (*Sandbox, error) { + resp, err := s.client.SuspendSandbox(ctx, &pb.SuspendSandboxRequest{ + Name: name, + Workspace: workspace, + }) + if err != nil { + return nil, converter.FromGRPCError(err) + } + return converter.SandboxFromProto(resp.GetSandbox()), nil +} + +func (s *sandboxClient) Resume(ctx context.Context, workspace, name string) (*Sandbox, error) { + resp, err := s.client.ResumeSandbox(ctx, &pb.ResumeSandboxRequest{ + Name: name, + Workspace: workspace, + }) + if err != nil { + return nil, converter.FromGRPCError(err) + } + return converter.SandboxFromProto(resp.GetSandbox()), nil +} + func (s *sandboxClient) AttachProvider(ctx context.Context, workspace, sandboxName, providerName string, expectedResourceVersion uint64) (*AttachProviderResult, error) { resp, err := s.client.AttachSandboxProvider(ctx, &pb.AttachSandboxProviderRequest{ SandboxName: sandboxName, @@ -140,6 +162,14 @@ func (s *sandboxClient) ListProviders(ctx context.Context, workspace, sandboxNam } func (s *sandboxClient) WaitReady(ctx context.Context, workspace, name string, opts ...WaitOptions) (*Sandbox, error) { + return s.waitForPhase(ctx, workspace, name, SandboxReady, opts...) +} + +func (s *sandboxClient) WaitSuspended(ctx context.Context, workspace, name string, opts ...WaitOptions) (*Sandbox, error) { + return s.waitForPhase(ctx, workspace, name, SandboxSuspended, opts...) +} + +func (s *sandboxClient) waitForPhase(ctx context.Context, workspace, name string, target SandboxPhase, opts ...WaitOptions) (*Sandbox, error) { interval := defaultPollInterval if len(opts) > 0 && opts[0].PollInterval > 0 { interval = opts[0].PollInterval @@ -150,7 +180,7 @@ func (s *sandboxClient) WaitReady(ctx context.Context, workspace, name string, o return nil, err } - if sb.Status.Phase == SandboxReady { + if sb.Status.Phase == target { return sb, nil } if sb.Status.Phase == SandboxError { @@ -172,7 +202,7 @@ func (s *sandboxClient) WaitReady(ctx context.Context, workspace, name string, o if err != nil { return nil, err } - if sb.Status.Phase == SandboxReady { + if sb.Status.Phase == target { return sb, nil } if sb.Status.Phase == SandboxError { diff --git a/sdk/go/openshell/v1/sandbox_client_test.go b/sdk/go/openshell/v1/sandbox_client_test.go index 2574348ec4..e2a8afa89d 100644 --- a/sdk/go/openshell/v1/sandbox_client_test.go +++ b/sdk/go/openshell/v1/sandbox_client_test.go @@ -125,6 +125,28 @@ func (s *mockSandboxServer) DeleteSandbox(_ context.Context, req *pb.DeleteSandb return &pb.DeleteSandboxResponse{Deleted: true}, nil } +func (s *mockSandboxServer) SuspendSandbox(_ context.Context, req *pb.SuspendSandboxRequest) (*pb.SandboxResponse, error) { + s.mu.Lock() + defer s.mu.Unlock() + sb, ok := s.sandboxes[req.GetName()] + if !ok { + return nil, status.Errorf(codes.NotFound, "sandbox %q not found", req.GetName()) + } + sb.Status.Phase = pb.SandboxPhase_SANDBOX_PHASE_SUSPENDED + return &pb.SandboxResponse{Sandbox: proto.Clone(sb).(*pb.Sandbox)}, nil +} + +func (s *mockSandboxServer) ResumeSandbox(_ context.Context, req *pb.ResumeSandboxRequest) (*pb.SandboxResponse, error) { + s.mu.Lock() + defer s.mu.Unlock() + sb, ok := s.sandboxes[req.GetName()] + if !ok { + return nil, status.Errorf(codes.NotFound, "sandbox %q not found", req.GetName()) + } + sb.Status.Phase = pb.SandboxPhase_SANDBOX_PHASE_RESUMING + return &pb.SandboxResponse{Sandbox: proto.Clone(sb).(*pb.Sandbox)}, nil +} + func (s *mockSandboxServer) AttachSandboxProvider(_ context.Context, req *pb.AttachSandboxProviderRequest) (*pb.AttachSandboxProviderResponse, error) { s.mu.Lock() defer s.mu.Unlock() @@ -358,6 +380,24 @@ func TestSandboxDelete_NotFound(t *testing.T) { assert.True(t, IsNotFound(err)) } +func TestSandboxSuspendAndResume(t *testing.T) { + mock := newMockSandboxServer() + mock.sandboxes["lifecycle"] = &pb.Sandbox{ + Metadata: &dm.ObjectMeta{Name: "lifecycle", Workspace: "team-a"}, + Status: &pb.SandboxStatus{Phase: pb.SandboxPhase_SANDBOX_PHASE_READY}, + } + client, cleanup := setupSandboxTest(t, mock) + defer cleanup() + + suspended, err := client.Suspend(context.Background(), "team-a", "lifecycle") + require.NoError(t, err) + assert.Equal(t, SandboxSuspended, suspended.Status.Phase) + + resuming, err := client.Resume(context.Background(), "team-a", "lifecycle") + require.NoError(t, err) + assert.Equal(t, SandboxResuming, resuming.Status.Phase) +} + // --- T030: AttachProvider, DetachProvider, ListProviders tests --- func TestSandboxAttachProvider(t *testing.T) { @@ -472,6 +512,20 @@ func TestSandboxListProviders_Error(t *testing.T) { // --- T031: WaitReady tests --- +func TestSandboxWaitSuspended_AlreadySuspended(t *testing.T) { + mock := newMockSandboxServer() + mock.sandboxes["sleeping"] = &pb.Sandbox{ + Metadata: &dm.ObjectMeta{Name: "sleeping"}, + Status: &pb.SandboxStatus{Phase: pb.SandboxPhase_SANDBOX_PHASE_SUSPENDED}, + } + client, cleanup := setupSandboxTest(t, mock) + defer cleanup() + + result, err := client.WaitSuspended(context.Background(), "default", "sleeping") + require.NoError(t, err) + assert.Equal(t, SandboxSuspended, result.Status.Phase) +} + func TestSandboxWaitReady_AlreadyReady(t *testing.T) { mock := newMockSandboxServer() mock.sandboxes["ready-sb"] = &pb.Sandbox{ diff --git a/sdk/go/openshell/v1/types.go b/sdk/go/openshell/v1/types.go index 012811cabb..955b1d4cfc 100644 --- a/sdk/go/openshell/v1/types.go +++ b/sdk/go/openshell/v1/types.go @@ -17,6 +17,9 @@ const ( SandboxError = types.SandboxError SandboxDeleting = types.SandboxDeleting SandboxUnknown = types.SandboxUnknown + SandboxSuspending = types.SandboxSuspending + SandboxSuspended = types.SandboxSuspended + SandboxResuming = types.SandboxResuming ) // EventType classifies watch events. diff --git a/sdk/go/openshell/v1/types/types.go b/sdk/go/openshell/v1/types/types.go index 01da4ba9ca..7e6190c060 100644 --- a/sdk/go/openshell/v1/types/types.go +++ b/sdk/go/openshell/v1/types/types.go @@ -15,6 +15,9 @@ const ( SandboxError SandboxPhase = "Error" SandboxDeleting SandboxPhase = "Deleting" SandboxUnknown SandboxPhase = "Unknown" + SandboxSuspending SandboxPhase = "Suspending" + SandboxSuspended SandboxPhase = "Suspended" + SandboxResuming SandboxPhase = "Resuming" ) // EventType classifies watch events. diff --git a/sdk/go/proto/openshellv1/openshell.pb.go b/sdk/go/proto/openshellv1/openshell.pb.go index 2696be0e0a..117e5652da 100644 --- a/sdk/go/proto/openshellv1/openshell.pb.go +++ b/sdk/go/proto/openshellv1/openshell.pb.go @@ -41,6 +41,9 @@ const ( SandboxPhase_SANDBOX_PHASE_ERROR SandboxPhase = 3 SandboxPhase_SANDBOX_PHASE_DELETING SandboxPhase = 4 SandboxPhase_SANDBOX_PHASE_UNKNOWN SandboxPhase = 5 + SandboxPhase_SANDBOX_PHASE_SUSPENDING SandboxPhase = 6 + SandboxPhase_SANDBOX_PHASE_SUSPENDED SandboxPhase = 7 + SandboxPhase_SANDBOX_PHASE_RESUMING SandboxPhase = 8 ) // Enum value maps for SandboxPhase. @@ -52,6 +55,9 @@ var ( 3: "SANDBOX_PHASE_ERROR", 4: "SANDBOX_PHASE_DELETING", 5: "SANDBOX_PHASE_UNKNOWN", + 6: "SANDBOX_PHASE_SUSPENDING", + 7: "SANDBOX_PHASE_SUSPENDED", + 8: "SANDBOX_PHASE_RESUMING", } SandboxPhase_value = map[string]int32{ "SANDBOX_PHASE_UNSPECIFIED": 0, @@ -60,6 +66,9 @@ var ( "SANDBOX_PHASE_ERROR": 3, "SANDBOX_PHASE_DELETING": 4, "SANDBOX_PHASE_UNKNOWN": 5, + "SANDBOX_PHASE_SUSPENDING": 6, + "SANDBOX_PHASE_SUSPENDED": 7, + "SANDBOX_PHASE_RESUMING": 8, } ) @@ -2128,6 +2137,116 @@ func (x *DeleteSandboxRequest) GetWorkspace() string { return "" } +// Suspend sandbox request. +type SuspendSandboxRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Sandbox name (canonical lookup key). + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Workspace scope. Empty defaults to "default". + Workspace string `protobuf:"bytes,2,opt,name=workspace,proto3" json:"workspace,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SuspendSandboxRequest) Reset() { + *x = SuspendSandboxRequest{} + mi := &file_openshell_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SuspendSandboxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SuspendSandboxRequest) ProtoMessage() {} + +func (x *SuspendSandboxRequest) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SuspendSandboxRequest.ProtoReflect.Descriptor instead. +func (*SuspendSandboxRequest) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{27} +} + +func (x *SuspendSandboxRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SuspendSandboxRequest) GetWorkspace() string { + if x != nil { + return x.Workspace + } + return "" +} + +// Resume sandbox request. +type ResumeSandboxRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Sandbox name (canonical lookup key). + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Workspace scope. Empty defaults to "default". + Workspace string `protobuf:"bytes,2,opt,name=workspace,proto3" json:"workspace,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResumeSandboxRequest) Reset() { + *x = ResumeSandboxRequest{} + mi := &file_openshell_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResumeSandboxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResumeSandboxRequest) ProtoMessage() {} + +func (x *ResumeSandboxRequest) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResumeSandboxRequest.ProtoReflect.Descriptor instead. +func (*ResumeSandboxRequest) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{28} +} + +func (x *ResumeSandboxRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ResumeSandboxRequest) GetWorkspace() string { + if x != nil { + return x.Workspace + } + return "" +} + // Sandbox response. type SandboxResponse struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -2138,7 +2257,7 @@ type SandboxResponse struct { func (x *SandboxResponse) Reset() { *x = SandboxResponse{} - mi := &file_openshell_proto_msgTypes[27] + mi := &file_openshell_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2150,7 +2269,7 @@ func (x *SandboxResponse) String() string { func (*SandboxResponse) ProtoMessage() {} func (x *SandboxResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[27] + mi := &file_openshell_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2163,7 +2282,7 @@ func (x *SandboxResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxResponse.ProtoReflect.Descriptor instead. func (*SandboxResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{27} + return file_openshell_proto_rawDescGZIP(), []int{29} } func (x *SandboxResponse) GetSandbox() *Sandbox { @@ -2183,7 +2302,7 @@ type ListSandboxesResponse struct { func (x *ListSandboxesResponse) Reset() { *x = ListSandboxesResponse{} - mi := &file_openshell_proto_msgTypes[28] + mi := &file_openshell_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2195,7 +2314,7 @@ func (x *ListSandboxesResponse) String() string { func (*ListSandboxesResponse) ProtoMessage() {} func (x *ListSandboxesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[28] + mi := &file_openshell_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2208,7 +2327,7 @@ func (x *ListSandboxesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxesResponse.ProtoReflect.Descriptor instead. func (*ListSandboxesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{28} + return file_openshell_proto_rawDescGZIP(), []int{30} } func (x *ListSandboxesResponse) GetSandboxes() []*Sandbox { @@ -2228,7 +2347,7 @@ type ListSandboxProvidersResponse struct { func (x *ListSandboxProvidersResponse) Reset() { *x = ListSandboxProvidersResponse{} - mi := &file_openshell_proto_msgTypes[29] + mi := &file_openshell_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2240,7 +2359,7 @@ func (x *ListSandboxProvidersResponse) String() string { func (*ListSandboxProvidersResponse) ProtoMessage() {} func (x *ListSandboxProvidersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[29] + mi := &file_openshell_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2253,7 +2372,7 @@ func (x *ListSandboxProvidersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxProvidersResponse.ProtoReflect.Descriptor instead. func (*ListSandboxProvidersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{29} + return file_openshell_proto_rawDescGZIP(), []int{31} } func (x *ListSandboxProvidersResponse) GetProviders() []*datamodelv1.Provider { @@ -2275,7 +2394,7 @@ type AttachSandboxProviderResponse struct { func (x *AttachSandboxProviderResponse) Reset() { *x = AttachSandboxProviderResponse{} - mi := &file_openshell_proto_msgTypes[30] + mi := &file_openshell_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2287,7 +2406,7 @@ func (x *AttachSandboxProviderResponse) String() string { func (*AttachSandboxProviderResponse) ProtoMessage() {} func (x *AttachSandboxProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[30] + mi := &file_openshell_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2300,7 +2419,7 @@ func (x *AttachSandboxProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AttachSandboxProviderResponse.ProtoReflect.Descriptor instead. func (*AttachSandboxProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{30} + return file_openshell_proto_rawDescGZIP(), []int{32} } func (x *AttachSandboxProviderResponse) GetSandbox() *Sandbox { @@ -2329,7 +2448,7 @@ type DetachSandboxProviderResponse struct { func (x *DetachSandboxProviderResponse) Reset() { *x = DetachSandboxProviderResponse{} - mi := &file_openshell_proto_msgTypes[31] + mi := &file_openshell_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2341,7 +2460,7 @@ func (x *DetachSandboxProviderResponse) String() string { func (*DetachSandboxProviderResponse) ProtoMessage() {} func (x *DetachSandboxProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[31] + mi := &file_openshell_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2354,7 +2473,7 @@ func (x *DetachSandboxProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DetachSandboxProviderResponse.ProtoReflect.Descriptor instead. func (*DetachSandboxProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{31} + return file_openshell_proto_rawDescGZIP(), []int{33} } func (x *DetachSandboxProviderResponse) GetSandbox() *Sandbox { @@ -2381,7 +2500,7 @@ type DeleteSandboxResponse struct { func (x *DeleteSandboxResponse) Reset() { *x = DeleteSandboxResponse{} - mi := &file_openshell_proto_msgTypes[32] + mi := &file_openshell_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2393,7 +2512,7 @@ func (x *DeleteSandboxResponse) String() string { func (*DeleteSandboxResponse) ProtoMessage() {} func (x *DeleteSandboxResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[32] + mi := &file_openshell_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2406,7 +2525,7 @@ func (x *DeleteSandboxResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteSandboxResponse.ProtoReflect.Descriptor instead. func (*DeleteSandboxResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{32} + return file_openshell_proto_rawDescGZIP(), []int{34} } func (x *DeleteSandboxResponse) GetDeleted() bool { @@ -2427,7 +2546,7 @@ type CreateSshSessionRequest struct { func (x *CreateSshSessionRequest) Reset() { *x = CreateSshSessionRequest{} - mi := &file_openshell_proto_msgTypes[33] + mi := &file_openshell_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2439,7 +2558,7 @@ func (x *CreateSshSessionRequest) String() string { func (*CreateSshSessionRequest) ProtoMessage() {} func (x *CreateSshSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[33] + mi := &file_openshell_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2452,7 +2571,7 @@ func (x *CreateSshSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSshSessionRequest.ProtoReflect.Descriptor instead. func (*CreateSshSessionRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{33} + return file_openshell_proto_rawDescGZIP(), []int{35} } func (x *CreateSshSessionRequest) GetSandboxId() string { @@ -2495,7 +2614,7 @@ type CreateSshSessionResponse struct { func (x *CreateSshSessionResponse) Reset() { *x = CreateSshSessionResponse{} - mi := &file_openshell_proto_msgTypes[34] + mi := &file_openshell_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2507,7 +2626,7 @@ func (x *CreateSshSessionResponse) String() string { func (*CreateSshSessionResponse) ProtoMessage() {} func (x *CreateSshSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[34] + mi := &file_openshell_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2520,7 +2639,7 @@ func (x *CreateSshSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateSshSessionResponse.ProtoReflect.Descriptor instead. func (*CreateSshSessionResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{34} + return file_openshell_proto_rawDescGZIP(), []int{36} } func (x *CreateSshSessionResponse) GetSandboxId() string { @@ -2591,7 +2710,7 @@ type ExposeServiceRequest struct { func (x *ExposeServiceRequest) Reset() { *x = ExposeServiceRequest{} - mi := &file_openshell_proto_msgTypes[35] + mi := &file_openshell_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2603,7 +2722,7 @@ func (x *ExposeServiceRequest) String() string { func (*ExposeServiceRequest) ProtoMessage() {} func (x *ExposeServiceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[35] + mi := &file_openshell_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2616,7 +2735,7 @@ func (x *ExposeServiceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExposeServiceRequest.ProtoReflect.Descriptor instead. func (*ExposeServiceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{35} + return file_openshell_proto_rawDescGZIP(), []int{37} } func (x *ExposeServiceRequest) GetSandbox() string { @@ -2669,7 +2788,7 @@ type GetServiceRequest struct { func (x *GetServiceRequest) Reset() { *x = GetServiceRequest{} - mi := &file_openshell_proto_msgTypes[36] + mi := &file_openshell_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2681,7 +2800,7 @@ func (x *GetServiceRequest) String() string { func (*GetServiceRequest) ProtoMessage() {} func (x *GetServiceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[36] + mi := &file_openshell_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2694,7 +2813,7 @@ func (x *GetServiceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetServiceRequest.ProtoReflect.Descriptor instead. func (*GetServiceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{36} + return file_openshell_proto_rawDescGZIP(), []int{38} } func (x *GetServiceRequest) GetSandbox() string { @@ -2737,7 +2856,7 @@ type ListServicesRequest struct { func (x *ListServicesRequest) Reset() { *x = ListServicesRequest{} - mi := &file_openshell_proto_msgTypes[37] + mi := &file_openshell_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2749,7 +2868,7 @@ func (x *ListServicesRequest) String() string { func (*ListServicesRequest) ProtoMessage() {} func (x *ListServicesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[37] + mi := &file_openshell_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2762,7 +2881,7 @@ func (x *ListServicesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServicesRequest.ProtoReflect.Descriptor instead. func (*ListServicesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{37} + return file_openshell_proto_rawDescGZIP(), []int{39} } func (x *ListServicesRequest) GetSandbox() string { @@ -2810,7 +2929,7 @@ type ListServicesResponse struct { func (x *ListServicesResponse) Reset() { *x = ListServicesResponse{} - mi := &file_openshell_proto_msgTypes[38] + mi := &file_openshell_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2822,7 +2941,7 @@ func (x *ListServicesResponse) String() string { func (*ListServicesResponse) ProtoMessage() {} func (x *ListServicesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[38] + mi := &file_openshell_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2835,7 +2954,7 @@ func (x *ListServicesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListServicesResponse.ProtoReflect.Descriptor instead. func (*ListServicesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{38} + return file_openshell_proto_rawDescGZIP(), []int{40} } func (x *ListServicesResponse) GetServices() []*ServiceEndpointResponse { @@ -2860,7 +2979,7 @@ type DeleteServiceRequest struct { func (x *DeleteServiceRequest) Reset() { *x = DeleteServiceRequest{} - mi := &file_openshell_proto_msgTypes[39] + mi := &file_openshell_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2872,7 +2991,7 @@ func (x *DeleteServiceRequest) String() string { func (*DeleteServiceRequest) ProtoMessage() {} func (x *DeleteServiceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[39] + mi := &file_openshell_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2885,7 +3004,7 @@ func (x *DeleteServiceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteServiceRequest.ProtoReflect.Descriptor instead. func (*DeleteServiceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{39} + return file_openshell_proto_rawDescGZIP(), []int{41} } func (x *DeleteServiceRequest) GetSandbox() string { @@ -2920,7 +3039,7 @@ type DeleteServiceResponse struct { func (x *DeleteServiceResponse) Reset() { *x = DeleteServiceResponse{} - mi := &file_openshell_proto_msgTypes[40] + mi := &file_openshell_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2932,7 +3051,7 @@ func (x *DeleteServiceResponse) String() string { func (*DeleteServiceResponse) ProtoMessage() {} func (x *DeleteServiceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[40] + mi := &file_openshell_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2945,7 +3064,7 @@ func (x *DeleteServiceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteServiceResponse.ProtoReflect.Descriptor instead. func (*DeleteServiceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{40} + return file_openshell_proto_rawDescGZIP(), []int{42} } func (x *DeleteServiceResponse) GetDeleted() bool { @@ -2976,7 +3095,7 @@ type ServiceEndpoint struct { func (x *ServiceEndpoint) Reset() { *x = ServiceEndpoint{} - mi := &file_openshell_proto_msgTypes[41] + mi := &file_openshell_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2988,7 +3107,7 @@ func (x *ServiceEndpoint) String() string { func (*ServiceEndpoint) ProtoMessage() {} func (x *ServiceEndpoint) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[41] + mi := &file_openshell_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3001,7 +3120,7 @@ func (x *ServiceEndpoint) ProtoReflect() protoreflect.Message { // Deprecated: Use ServiceEndpoint.ProtoReflect.Descriptor instead. func (*ServiceEndpoint) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{41} + return file_openshell_proto_rawDescGZIP(), []int{43} } func (x *ServiceEndpoint) GetMetadata() *datamodelv1.ObjectMeta { @@ -3057,7 +3176,7 @@ type ServiceEndpointResponse struct { func (x *ServiceEndpointResponse) Reset() { *x = ServiceEndpointResponse{} - mi := &file_openshell_proto_msgTypes[42] + mi := &file_openshell_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3069,7 +3188,7 @@ func (x *ServiceEndpointResponse) String() string { func (*ServiceEndpointResponse) ProtoMessage() {} func (x *ServiceEndpointResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[42] + mi := &file_openshell_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3082,7 +3201,7 @@ func (x *ServiceEndpointResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ServiceEndpointResponse.ProtoReflect.Descriptor instead. func (*ServiceEndpointResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{42} + return file_openshell_proto_rawDescGZIP(), []int{44} } func (x *ServiceEndpointResponse) GetEndpoint() *ServiceEndpoint { @@ -3110,7 +3229,7 @@ type RevokeSshSessionRequest struct { func (x *RevokeSshSessionRequest) Reset() { *x = RevokeSshSessionRequest{} - mi := &file_openshell_proto_msgTypes[43] + mi := &file_openshell_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3122,7 +3241,7 @@ func (x *RevokeSshSessionRequest) String() string { func (*RevokeSshSessionRequest) ProtoMessage() {} func (x *RevokeSshSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[43] + mi := &file_openshell_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3135,7 +3254,7 @@ func (x *RevokeSshSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeSshSessionRequest.ProtoReflect.Descriptor instead. func (*RevokeSshSessionRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{43} + return file_openshell_proto_rawDescGZIP(), []int{45} } func (x *RevokeSshSessionRequest) GetToken() string { @@ -3156,7 +3275,7 @@ type RevokeSshSessionResponse struct { func (x *RevokeSshSessionResponse) Reset() { *x = RevokeSshSessionResponse{} - mi := &file_openshell_proto_msgTypes[44] + mi := &file_openshell_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3168,7 +3287,7 @@ func (x *RevokeSshSessionResponse) String() string { func (*RevokeSshSessionResponse) ProtoMessage() {} func (x *RevokeSshSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[44] + mi := &file_openshell_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3181,7 +3300,7 @@ func (x *RevokeSshSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeSshSessionResponse.ProtoReflect.Descriptor instead. func (*RevokeSshSessionResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{44} + return file_openshell_proto_rawDescGZIP(), []int{46} } func (x *RevokeSshSessionResponse) GetRevoked() bool { @@ -3218,7 +3337,7 @@ type ExecSandboxRequest struct { func (x *ExecSandboxRequest) Reset() { *x = ExecSandboxRequest{} - mi := &file_openshell_proto_msgTypes[45] + mi := &file_openshell_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3230,7 +3349,7 @@ func (x *ExecSandboxRequest) String() string { func (*ExecSandboxRequest) ProtoMessage() {} func (x *ExecSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[45] + mi := &file_openshell_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3243,7 +3362,7 @@ func (x *ExecSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxRequest.ProtoReflect.Descriptor instead. func (*ExecSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{45} + return file_openshell_proto_rawDescGZIP(), []int{47} } func (x *ExecSandboxRequest) GetSandboxId() string { @@ -3319,7 +3438,7 @@ type ExecSandboxStdout struct { func (x *ExecSandboxStdout) Reset() { *x = ExecSandboxStdout{} - mi := &file_openshell_proto_msgTypes[46] + mi := &file_openshell_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3331,7 +3450,7 @@ func (x *ExecSandboxStdout) String() string { func (*ExecSandboxStdout) ProtoMessage() {} func (x *ExecSandboxStdout) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[46] + mi := &file_openshell_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3344,7 +3463,7 @@ func (x *ExecSandboxStdout) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxStdout.ProtoReflect.Descriptor instead. func (*ExecSandboxStdout) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{46} + return file_openshell_proto_rawDescGZIP(), []int{48} } func (x *ExecSandboxStdout) GetData() []byte { @@ -3364,7 +3483,7 @@ type ExecSandboxStderr struct { func (x *ExecSandboxStderr) Reset() { *x = ExecSandboxStderr{} - mi := &file_openshell_proto_msgTypes[47] + mi := &file_openshell_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3376,7 +3495,7 @@ func (x *ExecSandboxStderr) String() string { func (*ExecSandboxStderr) ProtoMessage() {} func (x *ExecSandboxStderr) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[47] + mi := &file_openshell_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3389,7 +3508,7 @@ func (x *ExecSandboxStderr) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxStderr.ProtoReflect.Descriptor instead. func (*ExecSandboxStderr) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{47} + return file_openshell_proto_rawDescGZIP(), []int{49} } func (x *ExecSandboxStderr) GetData() []byte { @@ -3409,7 +3528,7 @@ type ExecSandboxExit struct { func (x *ExecSandboxExit) Reset() { *x = ExecSandboxExit{} - mi := &file_openshell_proto_msgTypes[48] + mi := &file_openshell_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3421,7 +3540,7 @@ func (x *ExecSandboxExit) String() string { func (*ExecSandboxExit) ProtoMessage() {} func (x *ExecSandboxExit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[48] + mi := &file_openshell_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3434,7 +3553,7 @@ func (x *ExecSandboxExit) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxExit.ProtoReflect.Descriptor instead. func (*ExecSandboxExit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{48} + return file_openshell_proto_rawDescGZIP(), []int{50} } func (x *ExecSandboxExit) GetExitCode() int32 { @@ -3459,7 +3578,7 @@ type ExecSandboxEvent struct { func (x *ExecSandboxEvent) Reset() { *x = ExecSandboxEvent{} - mi := &file_openshell_proto_msgTypes[49] + mi := &file_openshell_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3471,7 +3590,7 @@ func (x *ExecSandboxEvent) String() string { func (*ExecSandboxEvent) ProtoMessage() {} func (x *ExecSandboxEvent) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[49] + mi := &file_openshell_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3484,7 +3603,7 @@ func (x *ExecSandboxEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxEvent.ProtoReflect.Descriptor instead. func (*ExecSandboxEvent) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{49} + return file_openshell_proto_rawDescGZIP(), []int{51} } func (x *ExecSandboxEvent) GetPayload() isExecSandboxEvent_Payload { @@ -3566,7 +3685,7 @@ type TcpForwardInit struct { func (x *TcpForwardInit) Reset() { *x = TcpForwardInit{} - mi := &file_openshell_proto_msgTypes[50] + mi := &file_openshell_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3578,7 +3697,7 @@ func (x *TcpForwardInit) String() string { func (*TcpForwardInit) ProtoMessage() {} func (x *TcpForwardInit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[50] + mi := &file_openshell_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3591,7 +3710,7 @@ func (x *TcpForwardInit) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpForwardInit.ProtoReflect.Descriptor instead. func (*TcpForwardInit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{50} + return file_openshell_proto_rawDescGZIP(), []int{52} } func (x *TcpForwardInit) GetSandboxId() string { @@ -3670,7 +3789,7 @@ type TcpForwardFrame struct { func (x *TcpForwardFrame) Reset() { *x = TcpForwardFrame{} - mi := &file_openshell_proto_msgTypes[51] + mi := &file_openshell_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3682,7 +3801,7 @@ func (x *TcpForwardFrame) String() string { func (*TcpForwardFrame) ProtoMessage() {} func (x *TcpForwardFrame) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[51] + mi := &file_openshell_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3695,7 +3814,7 @@ func (x *TcpForwardFrame) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpForwardFrame.ProtoReflect.Descriptor instead. func (*TcpForwardFrame) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{51} + return file_openshell_proto_rawDescGZIP(), []int{53} } func (x *TcpForwardFrame) GetPayload() isTcpForwardFrame_Payload { @@ -3754,7 +3873,7 @@ type ExecSandboxInput struct { func (x *ExecSandboxInput) Reset() { *x = ExecSandboxInput{} - mi := &file_openshell_proto_msgTypes[52] + mi := &file_openshell_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3766,7 +3885,7 @@ func (x *ExecSandboxInput) String() string { func (*ExecSandboxInput) ProtoMessage() {} func (x *ExecSandboxInput) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[52] + mi := &file_openshell_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3779,7 +3898,7 @@ func (x *ExecSandboxInput) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxInput.ProtoReflect.Descriptor instead. func (*ExecSandboxInput) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{52} + return file_openshell_proto_rawDescGZIP(), []int{54} } func (x *ExecSandboxInput) GetPayload() isExecSandboxInput_Payload { @@ -3852,7 +3971,7 @@ type ExecSandboxWindowResize struct { func (x *ExecSandboxWindowResize) Reset() { *x = ExecSandboxWindowResize{} - mi := &file_openshell_proto_msgTypes[53] + mi := &file_openshell_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3864,7 +3983,7 @@ func (x *ExecSandboxWindowResize) String() string { func (*ExecSandboxWindowResize) ProtoMessage() {} func (x *ExecSandboxWindowResize) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[53] + mi := &file_openshell_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3877,7 +3996,7 @@ func (x *ExecSandboxWindowResize) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecSandboxWindowResize.ProtoReflect.Descriptor instead. func (*ExecSandboxWindowResize) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{53} + return file_openshell_proto_rawDescGZIP(), []int{55} } func (x *ExecSandboxWindowResize) GetCols() uint32 { @@ -3914,7 +4033,7 @@ type SshSession struct { func (x *SshSession) Reset() { *x = SshSession{} - mi := &file_openshell_proto_msgTypes[54] + mi := &file_openshell_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3926,7 +4045,7 @@ func (x *SshSession) String() string { func (*SshSession) ProtoMessage() {} func (x *SshSession) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[54] + mi := &file_openshell_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3939,7 +4058,7 @@ func (x *SshSession) ProtoReflect() protoreflect.Message { // Deprecated: Use SshSession.ProtoReflect.Descriptor instead. func (*SshSession) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{54} + return file_openshell_proto_rawDescGZIP(), []int{56} } func (x *SshSession) GetMetadata() *datamodelv1.ObjectMeta { @@ -4007,7 +4126,7 @@ type WatchSandboxRequest struct { func (x *WatchSandboxRequest) Reset() { *x = WatchSandboxRequest{} - mi := &file_openshell_proto_msgTypes[55] + mi := &file_openshell_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4019,7 +4138,7 @@ func (x *WatchSandboxRequest) String() string { func (*WatchSandboxRequest) ProtoMessage() {} func (x *WatchSandboxRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[55] + mi := &file_openshell_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4032,7 +4151,7 @@ func (x *WatchSandboxRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchSandboxRequest.ProtoReflect.Descriptor instead. func (*WatchSandboxRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{55} + return file_openshell_proto_rawDescGZIP(), []int{57} } func (x *WatchSandboxRequest) GetId() string { @@ -4122,7 +4241,7 @@ type SandboxStreamEvent struct { func (x *SandboxStreamEvent) Reset() { *x = SandboxStreamEvent{} - mi := &file_openshell_proto_msgTypes[56] + mi := &file_openshell_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4134,7 +4253,7 @@ func (x *SandboxStreamEvent) String() string { func (*SandboxStreamEvent) ProtoMessage() {} func (x *SandboxStreamEvent) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[56] + mi := &file_openshell_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4147,7 +4266,7 @@ func (x *SandboxStreamEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxStreamEvent.ProtoReflect.Descriptor instead. func (*SandboxStreamEvent) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{56} + return file_openshell_proto_rawDescGZIP(), []int{58} } func (x *SandboxStreamEvent) GetPayload() isSandboxStreamEvent_Payload { @@ -4260,7 +4379,7 @@ type SandboxLogLine struct { func (x *SandboxLogLine) Reset() { *x = SandboxLogLine{} - mi := &file_openshell_proto_msgTypes[57] + mi := &file_openshell_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4272,7 +4391,7 @@ func (x *SandboxLogLine) String() string { func (*SandboxLogLine) ProtoMessage() {} func (x *SandboxLogLine) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[57] + mi := &file_openshell_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4285,7 +4404,7 @@ func (x *SandboxLogLine) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxLogLine.ProtoReflect.Descriptor instead. func (*SandboxLogLine) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{57} + return file_openshell_proto_rawDescGZIP(), []int{59} } func (x *SandboxLogLine) GetSandboxId() string { @@ -4346,7 +4465,7 @@ type SandboxStreamWarning struct { func (x *SandboxStreamWarning) Reset() { *x = SandboxStreamWarning{} - mi := &file_openshell_proto_msgTypes[58] + mi := &file_openshell_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4358,7 +4477,7 @@ func (x *SandboxStreamWarning) String() string { func (*SandboxStreamWarning) ProtoMessage() {} func (x *SandboxStreamWarning) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[58] + mi := &file_openshell_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4371,7 +4490,7 @@ func (x *SandboxStreamWarning) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxStreamWarning.ProtoReflect.Descriptor instead. func (*SandboxStreamWarning) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{58} + return file_openshell_proto_rawDescGZIP(), []int{60} } func (x *SandboxStreamWarning) GetMessage() string { @@ -4393,7 +4512,7 @@ type CreateProviderRequest struct { func (x *CreateProviderRequest) Reset() { *x = CreateProviderRequest{} - mi := &file_openshell_proto_msgTypes[59] + mi := &file_openshell_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4405,7 +4524,7 @@ func (x *CreateProviderRequest) String() string { func (*CreateProviderRequest) ProtoMessage() {} func (x *CreateProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[59] + mi := &file_openshell_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4418,7 +4537,7 @@ func (x *CreateProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateProviderRequest.ProtoReflect.Descriptor instead. func (*CreateProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{59} + return file_openshell_proto_rawDescGZIP(), []int{61} } func (x *CreateProviderRequest) GetProvider() *datamodelv1.Provider { @@ -4447,7 +4566,7 @@ type GetProviderRequest struct { func (x *GetProviderRequest) Reset() { *x = GetProviderRequest{} - mi := &file_openshell_proto_msgTypes[60] + mi := &file_openshell_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4459,7 +4578,7 @@ func (x *GetProviderRequest) String() string { func (*GetProviderRequest) ProtoMessage() {} func (x *GetProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[60] + mi := &file_openshell_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4472,7 +4591,7 @@ func (x *GetProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRequest.ProtoReflect.Descriptor instead. func (*GetProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{60} + return file_openshell_proto_rawDescGZIP(), []int{62} } func (x *GetProviderRequest) GetName() string { @@ -4504,7 +4623,7 @@ type ListProvidersRequest struct { func (x *ListProvidersRequest) Reset() { *x = ListProvidersRequest{} - mi := &file_openshell_proto_msgTypes[61] + mi := &file_openshell_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4516,7 +4635,7 @@ func (x *ListProvidersRequest) String() string { func (*ListProvidersRequest) ProtoMessage() {} func (x *ListProvidersRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[61] + mi := &file_openshell_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4529,7 +4648,7 @@ func (x *ListProvidersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProvidersRequest.ProtoReflect.Descriptor instead. func (*ListProvidersRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{61} + return file_openshell_proto_rawDescGZIP(), []int{63} } func (x *ListProvidersRequest) GetLimit() uint32 { @@ -4575,7 +4694,7 @@ type UpdateProviderRequest struct { func (x *UpdateProviderRequest) Reset() { *x = UpdateProviderRequest{} - mi := &file_openshell_proto_msgTypes[62] + mi := &file_openshell_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4587,7 +4706,7 @@ func (x *UpdateProviderRequest) String() string { func (*UpdateProviderRequest) ProtoMessage() {} func (x *UpdateProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[62] + mi := &file_openshell_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4600,7 +4719,7 @@ func (x *UpdateProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderRequest.ProtoReflect.Descriptor instead. func (*UpdateProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{62} + return file_openshell_proto_rawDescGZIP(), []int{64} } func (x *UpdateProviderRequest) GetProvider() *datamodelv1.Provider { @@ -4636,7 +4755,7 @@ type DeleteProviderRequest struct { func (x *DeleteProviderRequest) Reset() { *x = DeleteProviderRequest{} - mi := &file_openshell_proto_msgTypes[63] + mi := &file_openshell_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4648,7 +4767,7 @@ func (x *DeleteProviderRequest) String() string { func (*DeleteProviderRequest) ProtoMessage() {} func (x *DeleteProviderRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[63] + mi := &file_openshell_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4661,7 +4780,7 @@ func (x *DeleteProviderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{63} + return file_openshell_proto_rawDescGZIP(), []int{65} } func (x *DeleteProviderRequest) GetName() string { @@ -4688,7 +4807,7 @@ type ProviderResponse struct { func (x *ProviderResponse) Reset() { *x = ProviderResponse{} - mi := &file_openshell_proto_msgTypes[64] + mi := &file_openshell_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4700,7 +4819,7 @@ func (x *ProviderResponse) String() string { func (*ProviderResponse) ProtoMessage() {} func (x *ProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[64] + mi := &file_openshell_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4713,7 +4832,7 @@ func (x *ProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderResponse.ProtoReflect.Descriptor instead. func (*ProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{64} + return file_openshell_proto_rawDescGZIP(), []int{66} } func (x *ProviderResponse) GetProvider() *datamodelv1.Provider { @@ -4733,7 +4852,7 @@ type ListProvidersResponse struct { func (x *ListProvidersResponse) Reset() { *x = ListProvidersResponse{} - mi := &file_openshell_proto_msgTypes[65] + mi := &file_openshell_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4745,7 +4864,7 @@ func (x *ListProvidersResponse) String() string { func (*ListProvidersResponse) ProtoMessage() {} func (x *ListProvidersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[65] + mi := &file_openshell_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4758,7 +4877,7 @@ func (x *ListProvidersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProvidersResponse.ProtoReflect.Descriptor instead. func (*ListProvidersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{65} + return file_openshell_proto_rawDescGZIP(), []int{67} } func (x *ListProvidersResponse) GetProviders() []*datamodelv1.Provider { @@ -4782,7 +4901,7 @@ type ListProviderProfilesRequest struct { func (x *ListProviderProfilesRequest) Reset() { *x = ListProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[66] + mi := &file_openshell_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4794,7 +4913,7 @@ func (x *ListProviderProfilesRequest) String() string { func (*ListProviderProfilesRequest) ProtoMessage() {} func (x *ListProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[66] + mi := &file_openshell_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4807,7 +4926,7 @@ func (x *ListProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*ListProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{66} + return file_openshell_proto_rawDescGZIP(), []int{68} } func (x *ListProviderProfilesRequest) GetLimit() uint32 { @@ -4845,7 +4964,7 @@ type GetProviderProfileRequest struct { func (x *GetProviderProfileRequest) Reset() { *x = GetProviderProfileRequest{} - mi := &file_openshell_proto_msgTypes[67] + mi := &file_openshell_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4857,7 +4976,7 @@ func (x *GetProviderProfileRequest) String() string { func (*GetProviderProfileRequest) ProtoMessage() {} func (x *GetProviderProfileRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[67] + mi := &file_openshell_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4870,7 +4989,7 @@ func (x *GetProviderProfileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderProfileRequest.ProtoReflect.Descriptor instead. func (*GetProviderProfileRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{67} + return file_openshell_proto_rawDescGZIP(), []int{69} } func (x *GetProviderProfileRequest) GetId() string { @@ -4898,7 +5017,7 @@ type ProviderProfileImportItem struct { func (x *ProviderProfileImportItem) Reset() { *x = ProviderProfileImportItem{} - mi := &file_openshell_proto_msgTypes[68] + mi := &file_openshell_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4910,7 +5029,7 @@ func (x *ProviderProfileImportItem) String() string { func (*ProviderProfileImportItem) ProtoMessage() {} func (x *ProviderProfileImportItem) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[68] + mi := &file_openshell_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4923,7 +5042,7 @@ func (x *ProviderProfileImportItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileImportItem.ProtoReflect.Descriptor instead. func (*ProviderProfileImportItem) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{68} + return file_openshell_proto_rawDescGZIP(), []int{70} } func (x *ProviderProfileImportItem) GetProfile() *ProviderProfile { @@ -4954,7 +5073,7 @@ type ProviderProfileDiagnostic struct { func (x *ProviderProfileDiagnostic) Reset() { *x = ProviderProfileDiagnostic{} - mi := &file_openshell_proto_msgTypes[69] + mi := &file_openshell_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4966,7 +5085,7 @@ func (x *ProviderProfileDiagnostic) String() string { func (*ProviderProfileDiagnostic) ProtoMessage() {} func (x *ProviderProfileDiagnostic) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[69] + mi := &file_openshell_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4979,7 +5098,7 @@ func (x *ProviderProfileDiagnostic) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileDiagnostic.ProtoReflect.Descriptor instead. func (*ProviderProfileDiagnostic) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{69} + return file_openshell_proto_rawDescGZIP(), []int{71} } func (x *ProviderProfileDiagnostic) GetSource() string { @@ -5036,7 +5155,7 @@ type ProviderCredentialTokenGrantAudienceOverride struct { func (x *ProviderCredentialTokenGrantAudienceOverride) Reset() { *x = ProviderCredentialTokenGrantAudienceOverride{} - mi := &file_openshell_proto_msgTypes[70] + mi := &file_openshell_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5048,7 +5167,7 @@ func (x *ProviderCredentialTokenGrantAudienceOverride) String() string { func (*ProviderCredentialTokenGrantAudienceOverride) ProtoMessage() {} func (x *ProviderCredentialTokenGrantAudienceOverride) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[70] + mi := &file_openshell_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5061,7 +5180,7 @@ func (x *ProviderCredentialTokenGrantAudienceOverride) ProtoReflect() protorefle // Deprecated: Use ProviderCredentialTokenGrantAudienceOverride.ProtoReflect.Descriptor instead. func (*ProviderCredentialTokenGrantAudienceOverride) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{70} + return file_openshell_proto_rawDescGZIP(), []int{72} } func (x *ProviderCredentialTokenGrantAudienceOverride) GetHost() string { @@ -5126,7 +5245,7 @@ type ProviderCredentialTokenGrant struct { func (x *ProviderCredentialTokenGrant) Reset() { *x = ProviderCredentialTokenGrant{} - mi := &file_openshell_proto_msgTypes[71] + mi := &file_openshell_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5138,7 +5257,7 @@ func (x *ProviderCredentialTokenGrant) String() string { func (*ProviderCredentialTokenGrant) ProtoMessage() {} func (x *ProviderCredentialTokenGrant) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[71] + mi := &file_openshell_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5151,7 +5270,7 @@ func (x *ProviderCredentialTokenGrant) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialTokenGrant.ProtoReflect.Descriptor instead. func (*ProviderCredentialTokenGrant) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{71} + return file_openshell_proto_rawDescGZIP(), []int{73} } func (x *ProviderCredentialTokenGrant) GetTokenEndpoint() string { @@ -5222,7 +5341,7 @@ type ProviderProfileCredential struct { func (x *ProviderProfileCredential) Reset() { *x = ProviderProfileCredential{} - mi := &file_openshell_proto_msgTypes[72] + mi := &file_openshell_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5234,7 +5353,7 @@ func (x *ProviderProfileCredential) String() string { func (*ProviderProfileCredential) ProtoMessage() {} func (x *ProviderProfileCredential) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[72] + mi := &file_openshell_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5247,7 +5366,7 @@ func (x *ProviderProfileCredential) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileCredential.ProtoReflect.Descriptor instead. func (*ProviderProfileCredential) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{72} + return file_openshell_proto_rawDescGZIP(), []int{74} } func (x *ProviderProfileCredential) GetName() string { @@ -5332,7 +5451,7 @@ type ProviderCredentialRefreshMaterial struct { func (x *ProviderCredentialRefreshMaterial) Reset() { *x = ProviderCredentialRefreshMaterial{} - mi := &file_openshell_proto_msgTypes[73] + mi := &file_openshell_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5344,7 +5463,7 @@ func (x *ProviderCredentialRefreshMaterial) String() string { func (*ProviderCredentialRefreshMaterial) ProtoMessage() {} func (x *ProviderCredentialRefreshMaterial) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[73] + mi := &file_openshell_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5357,7 +5476,7 @@ func (x *ProviderCredentialRefreshMaterial) ProtoReflect() protoreflect.Message // Deprecated: Use ProviderCredentialRefreshMaterial.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefreshMaterial) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{73} + return file_openshell_proto_rawDescGZIP(), []int{75} } func (x *ProviderCredentialRefreshMaterial) GetName() string { @@ -5402,7 +5521,7 @@ type ProviderCredentialRefreshOutput struct { func (x *ProviderCredentialRefreshOutput) Reset() { *x = ProviderCredentialRefreshOutput{} - mi := &file_openshell_proto_msgTypes[74] + mi := &file_openshell_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5414,7 +5533,7 @@ func (x *ProviderCredentialRefreshOutput) String() string { func (*ProviderCredentialRefreshOutput) ProtoMessage() {} func (x *ProviderCredentialRefreshOutput) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[74] + mi := &file_openshell_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5427,7 +5546,7 @@ func (x *ProviderCredentialRefreshOutput) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialRefreshOutput.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefreshOutput) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{74} + return file_openshell_proto_rawDescGZIP(), []int{76} } func (x *ProviderCredentialRefreshOutput) GetOutput() string { @@ -5459,7 +5578,7 @@ type ProviderCredentialRefresh struct { func (x *ProviderCredentialRefresh) Reset() { *x = ProviderCredentialRefresh{} - mi := &file_openshell_proto_msgTypes[75] + mi := &file_openshell_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5471,7 +5590,7 @@ func (x *ProviderCredentialRefresh) String() string { func (*ProviderCredentialRefresh) ProtoMessage() {} func (x *ProviderCredentialRefresh) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[75] + mi := &file_openshell_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5484,7 +5603,7 @@ func (x *ProviderCredentialRefresh) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialRefresh.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefresh) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{75} + return file_openshell_proto_rawDescGZIP(), []int{77} } func (x *ProviderCredentialRefresh) GetStrategy() ProviderCredentialRefreshStrategy { @@ -5553,7 +5672,7 @@ type ProviderCredentialRefreshStatus struct { func (x *ProviderCredentialRefreshStatus) Reset() { *x = ProviderCredentialRefreshStatus{} - mi := &file_openshell_proto_msgTypes[76] + mi := &file_openshell_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5565,7 +5684,7 @@ func (x *ProviderCredentialRefreshStatus) String() string { func (*ProviderCredentialRefreshStatus) ProtoMessage() {} func (x *ProviderCredentialRefreshStatus) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[76] + mi := &file_openshell_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5578,7 +5697,7 @@ func (x *ProviderCredentialRefreshStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderCredentialRefreshStatus.ProtoReflect.Descriptor instead. func (*ProviderCredentialRefreshStatus) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{76} + return file_openshell_proto_rawDescGZIP(), []int{78} } func (x *ProviderCredentialRefreshStatus) GetProviderName() string { @@ -5655,7 +5774,7 @@ type ProviderProfileDiscovery struct { func (x *ProviderProfileDiscovery) Reset() { *x = ProviderProfileDiscovery{} - mi := &file_openshell_proto_msgTypes[77] + mi := &file_openshell_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5667,7 +5786,7 @@ func (x *ProviderProfileDiscovery) String() string { func (*ProviderProfileDiscovery) ProtoMessage() {} func (x *ProviderProfileDiscovery) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[77] + mi := &file_openshell_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5680,7 +5799,7 @@ func (x *ProviderProfileDiscovery) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileDiscovery.ProtoReflect.Descriptor instead. func (*ProviderProfileDiscovery) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{77} + return file_openshell_proto_rawDescGZIP(), []int{79} } func (x *ProviderProfileDiscovery) GetCredentials() []string { @@ -5719,7 +5838,7 @@ type StoredProviderCredentialRefreshState struct { func (x *StoredProviderCredentialRefreshState) Reset() { *x = StoredProviderCredentialRefreshState{} - mi := &file_openshell_proto_msgTypes[78] + mi := &file_openshell_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5731,7 +5850,7 @@ func (x *StoredProviderCredentialRefreshState) String() string { func (*StoredProviderCredentialRefreshState) ProtoMessage() {} func (x *StoredProviderCredentialRefreshState) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[78] + mi := &file_openshell_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5744,7 +5863,7 @@ func (x *StoredProviderCredentialRefreshState) ProtoReflect() protoreflect.Messa // Deprecated: Use StoredProviderCredentialRefreshState.ProtoReflect.Descriptor instead. func (*StoredProviderCredentialRefreshState) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{78} + return file_openshell_proto_rawDescGZIP(), []int{80} } func (x *StoredProviderCredentialRefreshState) GetMetadata() *datamodelv1.ObjectMeta { @@ -5878,7 +5997,7 @@ type GetProviderRefreshStatusRequest struct { func (x *GetProviderRefreshStatusRequest) Reset() { *x = GetProviderRefreshStatusRequest{} - mi := &file_openshell_proto_msgTypes[79] + mi := &file_openshell_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5890,7 +6009,7 @@ func (x *GetProviderRefreshStatusRequest) String() string { func (*GetProviderRefreshStatusRequest) ProtoMessage() {} func (x *GetProviderRefreshStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[79] + mi := &file_openshell_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5903,7 +6022,7 @@ func (x *GetProviderRefreshStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRefreshStatusRequest.ProtoReflect.Descriptor instead. func (*GetProviderRefreshStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{79} + return file_openshell_proto_rawDescGZIP(), []int{81} } func (x *GetProviderRefreshStatusRequest) GetProvider() string { @@ -5936,7 +6055,7 @@ type GetProviderRefreshStatusResponse struct { func (x *GetProviderRefreshStatusResponse) Reset() { *x = GetProviderRefreshStatusResponse{} - mi := &file_openshell_proto_msgTypes[80] + mi := &file_openshell_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5948,7 +6067,7 @@ func (x *GetProviderRefreshStatusResponse) String() string { func (*GetProviderRefreshStatusResponse) ProtoMessage() {} func (x *GetProviderRefreshStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[80] + mi := &file_openshell_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5961,7 +6080,7 @@ func (x *GetProviderRefreshStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRefreshStatusResponse.ProtoReflect.Descriptor instead. func (*GetProviderRefreshStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{80} + return file_openshell_proto_rawDescGZIP(), []int{82} } func (x *GetProviderRefreshStatusResponse) GetCredentials() []*ProviderCredentialRefreshStatus { @@ -5987,7 +6106,7 @@ type ConfigureProviderRefreshRequest struct { func (x *ConfigureProviderRefreshRequest) Reset() { *x = ConfigureProviderRefreshRequest{} - mi := &file_openshell_proto_msgTypes[81] + mi := &file_openshell_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5999,7 +6118,7 @@ func (x *ConfigureProviderRefreshRequest) String() string { func (*ConfigureProviderRefreshRequest) ProtoMessage() {} func (x *ConfigureProviderRefreshRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[81] + mi := &file_openshell_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6012,7 +6131,7 @@ func (x *ConfigureProviderRefreshRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureProviderRefreshRequest.ProtoReflect.Descriptor instead. func (*ConfigureProviderRefreshRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{81} + return file_openshell_proto_rawDescGZIP(), []int{83} } func (x *ConfigureProviderRefreshRequest) GetProvider() string { @@ -6073,7 +6192,7 @@ type ConfigureProviderRefreshResponse struct { func (x *ConfigureProviderRefreshResponse) Reset() { *x = ConfigureProviderRefreshResponse{} - mi := &file_openshell_proto_msgTypes[82] + mi := &file_openshell_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6085,7 +6204,7 @@ func (x *ConfigureProviderRefreshResponse) String() string { func (*ConfigureProviderRefreshResponse) ProtoMessage() {} func (x *ConfigureProviderRefreshResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[82] + mi := &file_openshell_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6098,7 +6217,7 @@ func (x *ConfigureProviderRefreshResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureProviderRefreshResponse.ProtoReflect.Descriptor instead. func (*ConfigureProviderRefreshResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{82} + return file_openshell_proto_rawDescGZIP(), []int{84} } func (x *ConfigureProviderRefreshResponse) GetStatus() *ProviderCredentialRefreshStatus { @@ -6120,7 +6239,7 @@ type RotateProviderCredentialRequest struct { func (x *RotateProviderCredentialRequest) Reset() { *x = RotateProviderCredentialRequest{} - mi := &file_openshell_proto_msgTypes[83] + mi := &file_openshell_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6132,7 +6251,7 @@ func (x *RotateProviderCredentialRequest) String() string { func (*RotateProviderCredentialRequest) ProtoMessage() {} func (x *RotateProviderCredentialRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[83] + mi := &file_openshell_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6145,7 +6264,7 @@ func (x *RotateProviderCredentialRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RotateProviderCredentialRequest.ProtoReflect.Descriptor instead. func (*RotateProviderCredentialRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{83} + return file_openshell_proto_rawDescGZIP(), []int{85} } func (x *RotateProviderCredentialRequest) GetProvider() string { @@ -6178,7 +6297,7 @@ type RotateProviderCredentialResponse struct { func (x *RotateProviderCredentialResponse) Reset() { *x = RotateProviderCredentialResponse{} - mi := &file_openshell_proto_msgTypes[84] + mi := &file_openshell_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6190,7 +6309,7 @@ func (x *RotateProviderCredentialResponse) String() string { func (*RotateProviderCredentialResponse) ProtoMessage() {} func (x *RotateProviderCredentialResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[84] + mi := &file_openshell_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6203,7 +6322,7 @@ func (x *RotateProviderCredentialResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RotateProviderCredentialResponse.ProtoReflect.Descriptor instead. func (*RotateProviderCredentialResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{84} + return file_openshell_proto_rawDescGZIP(), []int{86} } func (x *RotateProviderCredentialResponse) GetStatus() *ProviderCredentialRefreshStatus { @@ -6225,7 +6344,7 @@ type DeleteProviderRefreshRequest struct { func (x *DeleteProviderRefreshRequest) Reset() { *x = DeleteProviderRefreshRequest{} - mi := &file_openshell_proto_msgTypes[85] + mi := &file_openshell_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6237,7 +6356,7 @@ func (x *DeleteProviderRefreshRequest) String() string { func (*DeleteProviderRefreshRequest) ProtoMessage() {} func (x *DeleteProviderRefreshRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[85] + mi := &file_openshell_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6250,7 +6369,7 @@ func (x *DeleteProviderRefreshRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRefreshRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderRefreshRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{85} + return file_openshell_proto_rawDescGZIP(), []int{87} } func (x *DeleteProviderRefreshRequest) GetProvider() string { @@ -6283,7 +6402,7 @@ type DeleteProviderRefreshResponse struct { func (x *DeleteProviderRefreshResponse) Reset() { *x = DeleteProviderRefreshResponse{} - mi := &file_openshell_proto_msgTypes[86] + mi := &file_openshell_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6295,7 +6414,7 @@ func (x *DeleteProviderRefreshResponse) String() string { func (*DeleteProviderRefreshResponse) ProtoMessage() {} func (x *DeleteProviderRefreshResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[86] + mi := &file_openshell_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6308,7 +6427,7 @@ func (x *DeleteProviderRefreshResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRefreshResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderRefreshResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{86} + return file_openshell_proto_rawDescGZIP(), []int{88} } func (x *DeleteProviderRefreshResponse) GetDeleted() bool { @@ -6348,7 +6467,7 @@ type ProviderProfile struct { func (x *ProviderProfile) Reset() { *x = ProviderProfile{} - mi := &file_openshell_proto_msgTypes[87] + mi := &file_openshell_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6360,7 +6479,7 @@ func (x *ProviderProfile) String() string { func (*ProviderProfile) ProtoMessage() {} func (x *ProviderProfile) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[87] + mi := &file_openshell_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6373,7 +6492,7 @@ func (x *ProviderProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfile.ProtoReflect.Descriptor instead. func (*ProviderProfile) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{87} + return file_openshell_proto_rawDescGZIP(), []int{89} } func (x *ProviderProfile) GetId() string { @@ -6478,7 +6597,7 @@ type StoredProviderProfile struct { func (x *StoredProviderProfile) Reset() { *x = StoredProviderProfile{} - mi := &file_openshell_proto_msgTypes[88] + mi := &file_openshell_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6490,7 +6609,7 @@ func (x *StoredProviderProfile) String() string { func (*StoredProviderProfile) ProtoMessage() {} func (x *StoredProviderProfile) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[88] + mi := &file_openshell_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6503,7 +6622,7 @@ func (x *StoredProviderProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredProviderProfile.ProtoReflect.Descriptor instead. func (*StoredProviderProfile) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{88} + return file_openshell_proto_rawDescGZIP(), []int{90} } func (x *StoredProviderProfile) GetMetadata() *datamodelv1.ObjectMeta { @@ -6530,7 +6649,7 @@ type ProviderProfileResponse struct { func (x *ProviderProfileResponse) Reset() { *x = ProviderProfileResponse{} - mi := &file_openshell_proto_msgTypes[89] + mi := &file_openshell_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6542,7 +6661,7 @@ func (x *ProviderProfileResponse) String() string { func (*ProviderProfileResponse) ProtoMessage() {} func (x *ProviderProfileResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[89] + mi := &file_openshell_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6555,7 +6674,7 @@ func (x *ProviderProfileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileResponse.ProtoReflect.Descriptor instead. func (*ProviderProfileResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{89} + return file_openshell_proto_rawDescGZIP(), []int{91} } func (x *ProviderProfileResponse) GetProfile() *ProviderProfile { @@ -6575,7 +6694,7 @@ type ListProviderProfilesResponse struct { func (x *ListProviderProfilesResponse) Reset() { *x = ListProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[90] + mi := &file_openshell_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6587,7 +6706,7 @@ func (x *ListProviderProfilesResponse) String() string { func (*ListProviderProfilesResponse) ProtoMessage() {} func (x *ListProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[90] + mi := &file_openshell_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6600,7 +6719,7 @@ func (x *ListProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*ListProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{90} + return file_openshell_proto_rawDescGZIP(), []int{92} } func (x *ListProviderProfilesResponse) GetProfiles() []*ProviderProfile { @@ -6623,7 +6742,7 @@ type ImportProviderProfilesRequest struct { func (x *ImportProviderProfilesRequest) Reset() { *x = ImportProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[91] + mi := &file_openshell_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6635,7 +6754,7 @@ func (x *ImportProviderProfilesRequest) String() string { func (*ImportProviderProfilesRequest) ProtoMessage() {} func (x *ImportProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[91] + mi := &file_openshell_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6648,7 +6767,7 @@ func (x *ImportProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*ImportProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{91} + return file_openshell_proto_rawDescGZIP(), []int{93} } func (x *ImportProviderProfilesRequest) GetProfiles() []*ProviderProfileImportItem { @@ -6677,7 +6796,7 @@ type ImportProviderProfilesResponse struct { func (x *ImportProviderProfilesResponse) Reset() { *x = ImportProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[92] + mi := &file_openshell_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6689,7 +6808,7 @@ func (x *ImportProviderProfilesResponse) String() string { func (*ImportProviderProfilesResponse) ProtoMessage() {} func (x *ImportProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[92] + mi := &file_openshell_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6702,7 +6821,7 @@ func (x *ImportProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*ImportProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{92} + return file_openshell_proto_rawDescGZIP(), []int{94} } func (x *ImportProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -6746,7 +6865,7 @@ type UpdateProviderProfilesRequest struct { func (x *UpdateProviderProfilesRequest) Reset() { *x = UpdateProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[93] + mi := &file_openshell_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6758,7 +6877,7 @@ func (x *UpdateProviderProfilesRequest) String() string { func (*UpdateProviderProfilesRequest) ProtoMessage() {} func (x *UpdateProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[93] + mi := &file_openshell_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6771,7 +6890,7 @@ func (x *UpdateProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*UpdateProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{93} + return file_openshell_proto_rawDescGZIP(), []int{95} } func (x *UpdateProviderProfilesRequest) GetProfile() *ProviderProfileImportItem { @@ -6814,7 +6933,7 @@ type UpdateProviderProfilesResponse struct { func (x *UpdateProviderProfilesResponse) Reset() { *x = UpdateProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[94] + mi := &file_openshell_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6826,7 +6945,7 @@ func (x *UpdateProviderProfilesResponse) String() string { func (*UpdateProviderProfilesResponse) ProtoMessage() {} func (x *UpdateProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[94] + mi := &file_openshell_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6839,7 +6958,7 @@ func (x *UpdateProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*UpdateProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{94} + return file_openshell_proto_rawDescGZIP(), []int{96} } func (x *UpdateProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -6876,7 +6995,7 @@ type LintProviderProfilesRequest struct { func (x *LintProviderProfilesRequest) Reset() { *x = LintProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[95] + mi := &file_openshell_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6888,7 +7007,7 @@ func (x *LintProviderProfilesRequest) String() string { func (*LintProviderProfilesRequest) ProtoMessage() {} func (x *LintProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[95] + mi := &file_openshell_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6901,7 +7020,7 @@ func (x *LintProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LintProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*LintProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{95} + return file_openshell_proto_rawDescGZIP(), []int{97} } func (x *LintProviderProfilesRequest) GetProfiles() []*ProviderProfileImportItem { @@ -6929,7 +7048,7 @@ type LintProviderProfilesResponse struct { func (x *LintProviderProfilesResponse) Reset() { *x = LintProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[96] + mi := &file_openshell_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6941,7 +7060,7 @@ func (x *LintProviderProfilesResponse) String() string { func (*LintProviderProfilesResponse) ProtoMessage() {} func (x *LintProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[96] + mi := &file_openshell_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6954,7 +7073,7 @@ func (x *LintProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LintProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*LintProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{96} + return file_openshell_proto_rawDescGZIP(), []int{98} } func (x *LintProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -6981,7 +7100,7 @@ type DeleteProviderResponse struct { func (x *DeleteProviderResponse) Reset() { *x = DeleteProviderResponse{} - mi := &file_openshell_proto_msgTypes[97] + mi := &file_openshell_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6993,7 +7112,7 @@ func (x *DeleteProviderResponse) String() string { func (*DeleteProviderResponse) ProtoMessage() {} func (x *DeleteProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[97] + mi := &file_openshell_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7006,7 +7125,7 @@ func (x *DeleteProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{97} + return file_openshell_proto_rawDescGZIP(), []int{99} } func (x *DeleteProviderResponse) GetDeleted() bool { @@ -7029,7 +7148,7 @@ type DeleteProviderProfileRequest struct { func (x *DeleteProviderProfileRequest) Reset() { *x = DeleteProviderProfileRequest{} - mi := &file_openshell_proto_msgTypes[98] + mi := &file_openshell_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7041,7 +7160,7 @@ func (x *DeleteProviderProfileRequest) String() string { func (*DeleteProviderProfileRequest) ProtoMessage() {} func (x *DeleteProviderProfileRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[98] + mi := &file_openshell_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7054,7 +7173,7 @@ func (x *DeleteProviderProfileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderProfileRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderProfileRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{98} + return file_openshell_proto_rawDescGZIP(), []int{100} } func (x *DeleteProviderProfileRequest) GetId() string { @@ -7081,7 +7200,7 @@ type DeleteProviderProfileResponse struct { func (x *DeleteProviderProfileResponse) Reset() { *x = DeleteProviderProfileResponse{} - mi := &file_openshell_proto_msgTypes[99] + mi := &file_openshell_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7093,7 +7212,7 @@ func (x *DeleteProviderProfileResponse) String() string { func (*DeleteProviderProfileResponse) ProtoMessage() {} func (x *DeleteProviderProfileResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[99] + mi := &file_openshell_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7106,7 +7225,7 @@ func (x *DeleteProviderProfileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderProfileResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderProfileResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{99} + return file_openshell_proto_rawDescGZIP(), []int{101} } func (x *DeleteProviderProfileResponse) GetDeleted() bool { @@ -7127,7 +7246,7 @@ type GetSandboxProviderEnvironmentRequest struct { func (x *GetSandboxProviderEnvironmentRequest) Reset() { *x = GetSandboxProviderEnvironmentRequest{} - mi := &file_openshell_proto_msgTypes[100] + mi := &file_openshell_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7139,7 +7258,7 @@ func (x *GetSandboxProviderEnvironmentRequest) String() string { func (*GetSandboxProviderEnvironmentRequest) ProtoMessage() {} func (x *GetSandboxProviderEnvironmentRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[100] + mi := &file_openshell_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7152,7 +7271,7 @@ func (x *GetSandboxProviderEnvironmentRequest) ProtoReflect() protoreflect.Messa // Deprecated: Use GetSandboxProviderEnvironmentRequest.ProtoReflect.Descriptor instead. func (*GetSandboxProviderEnvironmentRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{100} + return file_openshell_proto_rawDescGZIP(), []int{102} } func (x *GetSandboxProviderEnvironmentRequest) GetSandboxId() string { @@ -7181,7 +7300,7 @@ type GetSandboxProviderEnvironmentResponse struct { func (x *GetSandboxProviderEnvironmentResponse) Reset() { *x = GetSandboxProviderEnvironmentResponse{} - mi := &file_openshell_proto_msgTypes[101] + mi := &file_openshell_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7193,7 +7312,7 @@ func (x *GetSandboxProviderEnvironmentResponse) String() string { func (*GetSandboxProviderEnvironmentResponse) ProtoMessage() {} func (x *GetSandboxProviderEnvironmentResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[101] + mi := &file_openshell_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7206,7 +7325,7 @@ func (x *GetSandboxProviderEnvironmentResponse) ProtoReflect() protoreflect.Mess // Deprecated: Use GetSandboxProviderEnvironmentResponse.ProtoReflect.Descriptor instead. func (*GetSandboxProviderEnvironmentResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{101} + return file_openshell_proto_rawDescGZIP(), []int{103} } func (x *GetSandboxProviderEnvironmentResponse) GetEnvironment() map[string]string { @@ -7284,7 +7403,7 @@ type UpdateConfigRequest struct { func (x *UpdateConfigRequest) Reset() { *x = UpdateConfigRequest{} - mi := &file_openshell_proto_msgTypes[102] + mi := &file_openshell_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7296,7 +7415,7 @@ func (x *UpdateConfigRequest) String() string { func (*UpdateConfigRequest) ProtoMessage() {} func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[102] + mi := &file_openshell_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7309,7 +7428,7 @@ func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateConfigRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{102} + return file_openshell_proto_rawDescGZIP(), []int{104} } func (x *UpdateConfigRequest) GetName() string { @@ -7399,7 +7518,7 @@ type PolicyMergeOperation struct { func (x *PolicyMergeOperation) Reset() { *x = PolicyMergeOperation{} - mi := &file_openshell_proto_msgTypes[103] + mi := &file_openshell_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7411,7 +7530,7 @@ func (x *PolicyMergeOperation) String() string { func (*PolicyMergeOperation) ProtoMessage() {} func (x *PolicyMergeOperation) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[103] + mi := &file_openshell_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7424,7 +7543,7 @@ func (x *PolicyMergeOperation) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyMergeOperation.ProtoReflect.Descriptor instead. func (*PolicyMergeOperation) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{103} + return file_openshell_proto_rawDescGZIP(), []int{105} } func (x *PolicyMergeOperation) GetOperation() isPolicyMergeOperation_Operation { @@ -7538,7 +7657,7 @@ type AddNetworkRule struct { func (x *AddNetworkRule) Reset() { *x = AddNetworkRule{} - mi := &file_openshell_proto_msgTypes[104] + mi := &file_openshell_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7550,7 +7669,7 @@ func (x *AddNetworkRule) String() string { func (*AddNetworkRule) ProtoMessage() {} func (x *AddNetworkRule) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[104] + mi := &file_openshell_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7563,7 +7682,7 @@ func (x *AddNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use AddNetworkRule.ProtoReflect.Descriptor instead. func (*AddNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{104} + return file_openshell_proto_rawDescGZIP(), []int{106} } func (x *AddNetworkRule) GetRuleName() string { @@ -7591,7 +7710,7 @@ type RemoveNetworkEndpoint struct { func (x *RemoveNetworkEndpoint) Reset() { *x = RemoveNetworkEndpoint{} - mi := &file_openshell_proto_msgTypes[105] + mi := &file_openshell_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7603,7 +7722,7 @@ func (x *RemoveNetworkEndpoint) String() string { func (*RemoveNetworkEndpoint) ProtoMessage() {} func (x *RemoveNetworkEndpoint) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[105] + mi := &file_openshell_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7616,7 +7735,7 @@ func (x *RemoveNetworkEndpoint) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkEndpoint.ProtoReflect.Descriptor instead. func (*RemoveNetworkEndpoint) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{105} + return file_openshell_proto_rawDescGZIP(), []int{107} } func (x *RemoveNetworkEndpoint) GetRuleName() string { @@ -7649,7 +7768,7 @@ type RemoveNetworkRule struct { func (x *RemoveNetworkRule) Reset() { *x = RemoveNetworkRule{} - mi := &file_openshell_proto_msgTypes[106] + mi := &file_openshell_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7661,7 +7780,7 @@ func (x *RemoveNetworkRule) String() string { func (*RemoveNetworkRule) ProtoMessage() {} func (x *RemoveNetworkRule) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[106] + mi := &file_openshell_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7674,7 +7793,7 @@ func (x *RemoveNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkRule.ProtoReflect.Descriptor instead. func (*RemoveNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{106} + return file_openshell_proto_rawDescGZIP(), []int{108} } func (x *RemoveNetworkRule) GetRuleName() string { @@ -7695,7 +7814,7 @@ type AddDenyRules struct { func (x *AddDenyRules) Reset() { *x = AddDenyRules{} - mi := &file_openshell_proto_msgTypes[107] + mi := &file_openshell_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7707,7 +7826,7 @@ func (x *AddDenyRules) String() string { func (*AddDenyRules) ProtoMessage() {} func (x *AddDenyRules) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[107] + mi := &file_openshell_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7720,7 +7839,7 @@ func (x *AddDenyRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddDenyRules.ProtoReflect.Descriptor instead. func (*AddDenyRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{107} + return file_openshell_proto_rawDescGZIP(), []int{109} } func (x *AddDenyRules) GetHost() string { @@ -7755,7 +7874,7 @@ type AddAllowRules struct { func (x *AddAllowRules) Reset() { *x = AddAllowRules{} - mi := &file_openshell_proto_msgTypes[108] + mi := &file_openshell_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7767,7 +7886,7 @@ func (x *AddAllowRules) String() string { func (*AddAllowRules) ProtoMessage() {} func (x *AddAllowRules) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[108] + mi := &file_openshell_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7780,7 +7899,7 @@ func (x *AddAllowRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddAllowRules.ProtoReflect.Descriptor instead. func (*AddAllowRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{108} + return file_openshell_proto_rawDescGZIP(), []int{110} } func (x *AddAllowRules) GetHost() string { @@ -7814,7 +7933,7 @@ type RemoveNetworkBinary struct { func (x *RemoveNetworkBinary) Reset() { *x = RemoveNetworkBinary{} - mi := &file_openshell_proto_msgTypes[109] + mi := &file_openshell_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7826,7 +7945,7 @@ func (x *RemoveNetworkBinary) String() string { func (*RemoveNetworkBinary) ProtoMessage() {} func (x *RemoveNetworkBinary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[109] + mi := &file_openshell_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7839,7 +7958,7 @@ func (x *RemoveNetworkBinary) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkBinary.ProtoReflect.Descriptor instead. func (*RemoveNetworkBinary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{109} + return file_openshell_proto_rawDescGZIP(), []int{111} } func (x *RemoveNetworkBinary) GetRuleName() string { @@ -7875,7 +7994,7 @@ type UpdateConfigResponse struct { func (x *UpdateConfigResponse) Reset() { *x = UpdateConfigResponse{} - mi := &file_openshell_proto_msgTypes[110] + mi := &file_openshell_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7887,7 +8006,7 @@ func (x *UpdateConfigResponse) String() string { func (*UpdateConfigResponse) ProtoMessage() {} func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[110] + mi := &file_openshell_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7900,7 +8019,7 @@ func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateConfigResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{110} + return file_openshell_proto_rawDescGZIP(), []int{112} } func (x *UpdateConfigResponse) GetVersion() uint32 { @@ -7955,7 +8074,7 @@ type GetSandboxPolicyStatusRequest struct { func (x *GetSandboxPolicyStatusRequest) Reset() { *x = GetSandboxPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[111] + mi := &file_openshell_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7967,7 +8086,7 @@ func (x *GetSandboxPolicyStatusRequest) String() string { func (*GetSandboxPolicyStatusRequest) ProtoMessage() {} func (x *GetSandboxPolicyStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[111] + mi := &file_openshell_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7980,7 +8099,7 @@ func (x *GetSandboxPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{111} + return file_openshell_proto_rawDescGZIP(), []int{113} } func (x *GetSandboxPolicyStatusRequest) GetName() string { @@ -8024,7 +8143,7 @@ type GetSandboxPolicyStatusResponse struct { func (x *GetSandboxPolicyStatusResponse) Reset() { *x = GetSandboxPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[112] + mi := &file_openshell_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8036,7 +8155,7 @@ func (x *GetSandboxPolicyStatusResponse) String() string { func (*GetSandboxPolicyStatusResponse) ProtoMessage() {} func (x *GetSandboxPolicyStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[112] + mi := &file_openshell_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8049,7 +8168,7 @@ func (x *GetSandboxPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{112} + return file_openshell_proto_rawDescGZIP(), []int{114} } func (x *GetSandboxPolicyStatusResponse) GetRevision() *SandboxPolicyRevision { @@ -8083,7 +8202,7 @@ type ListSandboxPoliciesRequest struct { func (x *ListSandboxPoliciesRequest) Reset() { *x = ListSandboxPoliciesRequest{} - mi := &file_openshell_proto_msgTypes[113] + mi := &file_openshell_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8095,7 +8214,7 @@ func (x *ListSandboxPoliciesRequest) String() string { func (*ListSandboxPoliciesRequest) ProtoMessage() {} func (x *ListSandboxPoliciesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[113] + mi := &file_openshell_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8108,7 +8227,7 @@ func (x *ListSandboxPoliciesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesRequest.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{113} + return file_openshell_proto_rawDescGZIP(), []int{115} } func (x *ListSandboxPoliciesRequest) GetName() string { @@ -8156,7 +8275,7 @@ type ListSandboxPoliciesResponse struct { func (x *ListSandboxPoliciesResponse) Reset() { *x = ListSandboxPoliciesResponse{} - mi := &file_openshell_proto_msgTypes[114] + mi := &file_openshell_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8168,7 +8287,7 @@ func (x *ListSandboxPoliciesResponse) String() string { func (*ListSandboxPoliciesResponse) ProtoMessage() {} func (x *ListSandboxPoliciesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[114] + mi := &file_openshell_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8181,7 +8300,7 @@ func (x *ListSandboxPoliciesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesResponse.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{114} + return file_openshell_proto_rawDescGZIP(), []int{116} } func (x *ListSandboxPoliciesResponse) GetRevisions() []*SandboxPolicyRevision { @@ -8208,7 +8327,7 @@ type ReportPolicyStatusRequest struct { func (x *ReportPolicyStatusRequest) Reset() { *x = ReportPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[115] + mi := &file_openshell_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8220,7 +8339,7 @@ func (x *ReportPolicyStatusRequest) String() string { func (*ReportPolicyStatusRequest) ProtoMessage() {} func (x *ReportPolicyStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[115] + mi := &file_openshell_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8233,7 +8352,7 @@ func (x *ReportPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{115} + return file_openshell_proto_rawDescGZIP(), []int{117} } func (x *ReportPolicyStatusRequest) GetSandboxId() string { @@ -8273,7 +8392,7 @@ type ReportPolicyStatusResponse struct { func (x *ReportPolicyStatusResponse) Reset() { *x = ReportPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[116] + mi := &file_openshell_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8285,7 +8404,7 @@ func (x *ReportPolicyStatusResponse) String() string { func (*ReportPolicyStatusResponse) ProtoMessage() {} func (x *ReportPolicyStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[116] + mi := &file_openshell_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8298,7 +8417,7 @@ func (x *ReportPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{116} + return file_openshell_proto_rawDescGZIP(), []int{118} } // A versioned policy revision with metadata. @@ -8326,7 +8445,7 @@ type SandboxPolicyRevision struct { func (x *SandboxPolicyRevision) Reset() { *x = SandboxPolicyRevision{} - mi := &file_openshell_proto_msgTypes[117] + mi := &file_openshell_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8338,7 +8457,7 @@ func (x *SandboxPolicyRevision) String() string { func (*SandboxPolicyRevision) ProtoMessage() {} func (x *SandboxPolicyRevision) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[117] + mi := &file_openshell_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8351,7 +8470,7 @@ func (x *SandboxPolicyRevision) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxPolicyRevision.ProtoReflect.Descriptor instead. func (*SandboxPolicyRevision) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{117} + return file_openshell_proto_rawDescGZIP(), []int{119} } func (x *SandboxPolicyRevision) GetVersion() uint32 { @@ -8431,7 +8550,7 @@ type GetSandboxLogsRequest struct { func (x *GetSandboxLogsRequest) Reset() { *x = GetSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[118] + mi := &file_openshell_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8443,7 +8562,7 @@ func (x *GetSandboxLogsRequest) String() string { func (*GetSandboxLogsRequest) ProtoMessage() {} func (x *GetSandboxLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[118] + mi := &file_openshell_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8456,7 +8575,7 @@ func (x *GetSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*GetSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{118} + return file_openshell_proto_rawDescGZIP(), []int{120} } func (x *GetSandboxLogsRequest) GetSandboxId() string { @@ -8514,7 +8633,7 @@ type PushSandboxLogsRequest struct { func (x *PushSandboxLogsRequest) Reset() { *x = PushSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[119] + mi := &file_openshell_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8526,7 +8645,7 @@ func (x *PushSandboxLogsRequest) String() string { func (*PushSandboxLogsRequest) ProtoMessage() {} func (x *PushSandboxLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[119] + mi := &file_openshell_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8539,7 +8658,7 @@ func (x *PushSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*PushSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{119} + return file_openshell_proto_rawDescGZIP(), []int{121} } func (x *PushSandboxLogsRequest) GetSandboxId() string { @@ -8565,7 +8684,7 @@ type PushSandboxLogsResponse struct { func (x *PushSandboxLogsResponse) Reset() { *x = PushSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[120] + mi := &file_openshell_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8577,7 +8696,7 @@ func (x *PushSandboxLogsResponse) String() string { func (*PushSandboxLogsResponse) ProtoMessage() {} func (x *PushSandboxLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[120] + mi := &file_openshell_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8590,7 +8709,7 @@ func (x *PushSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*PushSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{120} + return file_openshell_proto_rawDescGZIP(), []int{122} } // Get sandbox logs response. @@ -8606,7 +8725,7 @@ type GetSandboxLogsResponse struct { func (x *GetSandboxLogsResponse) Reset() { *x = GetSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[121] + mi := &file_openshell_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8618,7 +8737,7 @@ func (x *GetSandboxLogsResponse) String() string { func (*GetSandboxLogsResponse) ProtoMessage() {} func (x *GetSandboxLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[121] + mi := &file_openshell_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8631,7 +8750,7 @@ func (x *GetSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*GetSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{121} + return file_openshell_proto_rawDescGZIP(), []int{123} } func (x *GetSandboxLogsResponse) GetLogs() []*SandboxLogLine { @@ -8664,7 +8783,7 @@ type SupervisorMessage struct { func (x *SupervisorMessage) Reset() { *x = SupervisorMessage{} - mi := &file_openshell_proto_msgTypes[122] + mi := &file_openshell_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8676,7 +8795,7 @@ func (x *SupervisorMessage) String() string { func (*SupervisorMessage) ProtoMessage() {} func (x *SupervisorMessage) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[122] + mi := &file_openshell_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8689,7 +8808,7 @@ func (x *SupervisorMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorMessage.ProtoReflect.Descriptor instead. func (*SupervisorMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{122} + return file_openshell_proto_rawDescGZIP(), []int{124} } func (x *SupervisorMessage) GetPayload() isSupervisorMessage_Payload { @@ -8780,7 +8899,7 @@ type GatewayMessage struct { func (x *GatewayMessage) Reset() { *x = GatewayMessage{} - mi := &file_openshell_proto_msgTypes[123] + mi := &file_openshell_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8792,7 +8911,7 @@ func (x *GatewayMessage) String() string { func (*GatewayMessage) ProtoMessage() {} func (x *GatewayMessage) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[123] + mi := &file_openshell_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8805,7 +8924,7 @@ func (x *GatewayMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use GatewayMessage.ProtoReflect.Descriptor instead. func (*GatewayMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{123} + return file_openshell_proto_rawDescGZIP(), []int{125} } func (x *GatewayMessage) GetPayload() isGatewayMessage_Payload { @@ -8907,7 +9026,7 @@ type SupervisorHello struct { func (x *SupervisorHello) Reset() { *x = SupervisorHello{} - mi := &file_openshell_proto_msgTypes[124] + mi := &file_openshell_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8919,7 +9038,7 @@ func (x *SupervisorHello) String() string { func (*SupervisorHello) ProtoMessage() {} func (x *SupervisorHello) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[124] + mi := &file_openshell_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8932,7 +9051,7 @@ func (x *SupervisorHello) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorHello.ProtoReflect.Descriptor instead. func (*SupervisorHello) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{124} + return file_openshell_proto_rawDescGZIP(), []int{126} } func (x *SupervisorHello) GetSandboxId() string { @@ -8962,7 +9081,7 @@ type SessionAccepted struct { func (x *SessionAccepted) Reset() { *x = SessionAccepted{} - mi := &file_openshell_proto_msgTypes[125] + mi := &file_openshell_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8974,7 +9093,7 @@ func (x *SessionAccepted) String() string { func (*SessionAccepted) ProtoMessage() {} func (x *SessionAccepted) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[125] + mi := &file_openshell_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8987,7 +9106,7 @@ func (x *SessionAccepted) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionAccepted.ProtoReflect.Descriptor instead. func (*SessionAccepted) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{125} + return file_openshell_proto_rawDescGZIP(), []int{127} } func (x *SessionAccepted) GetSessionId() string { @@ -9015,7 +9134,7 @@ type SessionRejected struct { func (x *SessionRejected) Reset() { *x = SessionRejected{} - mi := &file_openshell_proto_msgTypes[126] + mi := &file_openshell_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9027,7 +9146,7 @@ func (x *SessionRejected) String() string { func (*SessionRejected) ProtoMessage() {} func (x *SessionRejected) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[126] + mi := &file_openshell_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9040,7 +9159,7 @@ func (x *SessionRejected) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionRejected.ProtoReflect.Descriptor instead. func (*SessionRejected) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{126} + return file_openshell_proto_rawDescGZIP(), []int{128} } func (x *SessionRejected) GetReason() string { @@ -9059,7 +9178,7 @@ type SupervisorHeartbeat struct { func (x *SupervisorHeartbeat) Reset() { *x = SupervisorHeartbeat{} - mi := &file_openshell_proto_msgTypes[127] + mi := &file_openshell_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9071,7 +9190,7 @@ func (x *SupervisorHeartbeat) String() string { func (*SupervisorHeartbeat) ProtoMessage() {} func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[127] + mi := &file_openshell_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9084,7 +9203,7 @@ func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorHeartbeat.ProtoReflect.Descriptor instead. func (*SupervisorHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{127} + return file_openshell_proto_rawDescGZIP(), []int{129} } // Gateway heartbeat. @@ -9096,7 +9215,7 @@ type GatewayHeartbeat struct { func (x *GatewayHeartbeat) Reset() { *x = GatewayHeartbeat{} - mi := &file_openshell_proto_msgTypes[128] + mi := &file_openshell_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9108,7 +9227,7 @@ func (x *GatewayHeartbeat) String() string { func (*GatewayHeartbeat) ProtoMessage() {} func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[128] + mi := &file_openshell_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9121,7 +9240,7 @@ func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { // Deprecated: Use GatewayHeartbeat.ProtoReflect.Descriptor instead. func (*GatewayHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{128} + return file_openshell_proto_rawDescGZIP(), []int{130} } // Gateway requests the supervisor to open a relay channel. @@ -9150,7 +9269,7 @@ type RelayOpen struct { func (x *RelayOpen) Reset() { *x = RelayOpen{} - mi := &file_openshell_proto_msgTypes[129] + mi := &file_openshell_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9162,7 +9281,7 @@ func (x *RelayOpen) String() string { func (*RelayOpen) ProtoMessage() {} func (x *RelayOpen) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[129] + mi := &file_openshell_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9175,7 +9294,7 @@ func (x *RelayOpen) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpen.ProtoReflect.Descriptor instead. func (*RelayOpen) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{129} + return file_openshell_proto_rawDescGZIP(), []int{131} } func (x *RelayOpen) GetChannelId() string { @@ -9242,7 +9361,7 @@ type SshRelayTarget struct { func (x *SshRelayTarget) Reset() { *x = SshRelayTarget{} - mi := &file_openshell_proto_msgTypes[130] + mi := &file_openshell_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9254,7 +9373,7 @@ func (x *SshRelayTarget) String() string { func (*SshRelayTarget) ProtoMessage() {} func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[130] + mi := &file_openshell_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9267,7 +9386,7 @@ func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use SshRelayTarget.ProtoReflect.Descriptor instead. func (*SshRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{130} + return file_openshell_proto_rawDescGZIP(), []int{132} } // TCP target dialed by the supervisor from inside the sandbox. @@ -9283,7 +9402,7 @@ type TcpRelayTarget struct { func (x *TcpRelayTarget) Reset() { *x = TcpRelayTarget{} - mi := &file_openshell_proto_msgTypes[131] + mi := &file_openshell_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9295,7 +9414,7 @@ func (x *TcpRelayTarget) String() string { func (*TcpRelayTarget) ProtoMessage() {} func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[131] + mi := &file_openshell_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9308,7 +9427,7 @@ func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpRelayTarget.ProtoReflect.Descriptor instead. func (*TcpRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{131} + return file_openshell_proto_rawDescGZIP(), []int{133} } func (x *TcpRelayTarget) GetHost() string { @@ -9336,7 +9455,7 @@ type RelayInit struct { func (x *RelayInit) Reset() { *x = RelayInit{} - mi := &file_openshell_proto_msgTypes[132] + mi := &file_openshell_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9348,7 +9467,7 @@ func (x *RelayInit) String() string { func (*RelayInit) ProtoMessage() {} func (x *RelayInit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[132] + mi := &file_openshell_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9361,7 +9480,7 @@ func (x *RelayInit) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayInit.ProtoReflect.Descriptor instead. func (*RelayInit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{132} + return file_openshell_proto_rawDescGZIP(), []int{134} } func (x *RelayInit) GetChannelId() string { @@ -9388,7 +9507,7 @@ type RelayFrame struct { func (x *RelayFrame) Reset() { *x = RelayFrame{} - mi := &file_openshell_proto_msgTypes[133] + mi := &file_openshell_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9400,7 +9519,7 @@ func (x *RelayFrame) String() string { func (*RelayFrame) ProtoMessage() {} func (x *RelayFrame) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[133] + mi := &file_openshell_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9413,7 +9532,7 @@ func (x *RelayFrame) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayFrame.ProtoReflect.Descriptor instead. func (*RelayFrame) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{133} + return file_openshell_proto_rawDescGZIP(), []int{135} } func (x *RelayFrame) GetPayload() isRelayFrame_Payload { @@ -9472,7 +9591,7 @@ type RelayOpenResult struct { func (x *RelayOpenResult) Reset() { *x = RelayOpenResult{} - mi := &file_openshell_proto_msgTypes[134] + mi := &file_openshell_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9484,7 +9603,7 @@ func (x *RelayOpenResult) String() string { func (*RelayOpenResult) ProtoMessage() {} func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[134] + mi := &file_openshell_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9497,7 +9616,7 @@ func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpenResult.ProtoReflect.Descriptor instead. func (*RelayOpenResult) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{134} + return file_openshell_proto_rawDescGZIP(), []int{136} } func (x *RelayOpenResult) GetChannelId() string { @@ -9534,7 +9653,7 @@ type RelayClose struct { func (x *RelayClose) Reset() { *x = RelayClose{} - mi := &file_openshell_proto_msgTypes[135] + mi := &file_openshell_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9546,7 +9665,7 @@ func (x *RelayClose) String() string { func (*RelayClose) ProtoMessage() {} func (x *RelayClose) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[135] + mi := &file_openshell_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9559,7 +9678,7 @@ func (x *RelayClose) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayClose.ProtoReflect.Descriptor instead. func (*RelayClose) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{135} + return file_openshell_proto_rawDescGZIP(), []int{137} } func (x *RelayClose) GetChannelId() string { @@ -9593,7 +9712,7 @@ type L7RequestSample struct { func (x *L7RequestSample) Reset() { *x = L7RequestSample{} - mi := &file_openshell_proto_msgTypes[136] + mi := &file_openshell_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9605,7 +9724,7 @@ func (x *L7RequestSample) String() string { func (*L7RequestSample) ProtoMessage() {} func (x *L7RequestSample) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[136] + mi := &file_openshell_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9618,7 +9737,7 @@ func (x *L7RequestSample) ProtoReflect() protoreflect.Message { // Deprecated: Use L7RequestSample.ProtoReflect.Descriptor instead. func (*L7RequestSample) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{136} + return file_openshell_proto_rawDescGZIP(), []int{138} } func (x *L7RequestSample) GetMethod() string { @@ -9692,7 +9811,7 @@ type DenialSummary struct { func (x *DenialSummary) Reset() { *x = DenialSummary{} - mi := &file_openshell_proto_msgTypes[137] + mi := &file_openshell_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9704,7 +9823,7 @@ func (x *DenialSummary) String() string { func (*DenialSummary) ProtoMessage() {} func (x *DenialSummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[137] + mi := &file_openshell_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9717,7 +9836,7 @@ func (x *DenialSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialSummary.ProtoReflect.Descriptor instead. func (*DenialSummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{137} + return file_openshell_proto_rawDescGZIP(), []int{139} } func (x *DenialSummary) GetSandboxId() string { @@ -9852,7 +9971,7 @@ type DenialGroupCount struct { func (x *DenialGroupCount) Reset() { *x = DenialGroupCount{} - mi := &file_openshell_proto_msgTypes[138] + mi := &file_openshell_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9864,7 +9983,7 @@ func (x *DenialGroupCount) String() string { func (*DenialGroupCount) ProtoMessage() {} func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[138] + mi := &file_openshell_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9877,7 +9996,7 @@ func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialGroupCount.ProtoReflect.Descriptor instead. func (*DenialGroupCount) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{138} + return file_openshell_proto_rawDescGZIP(), []int{140} } func (x *DenialGroupCount) GetDenyGroup() string { @@ -9910,7 +10029,7 @@ type NetworkActivitySummary struct { func (x *NetworkActivitySummary) Reset() { *x = NetworkActivitySummary{} - mi := &file_openshell_proto_msgTypes[139] + mi := &file_openshell_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9922,7 +10041,7 @@ func (x *NetworkActivitySummary) String() string { func (*NetworkActivitySummary) ProtoMessage() {} func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[139] + mi := &file_openshell_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9935,7 +10054,7 @@ func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkActivitySummary.ProtoReflect.Descriptor instead. func (*NetworkActivitySummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{139} + return file_openshell_proto_rawDescGZIP(), []int{141} } func (x *NetworkActivitySummary) GetNetworkActivityCount() uint32 { @@ -10009,7 +10128,7 @@ type PolicyChunk struct { func (x *PolicyChunk) Reset() { *x = PolicyChunk{} - mi := &file_openshell_proto_msgTypes[140] + mi := &file_openshell_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10021,7 +10140,7 @@ func (x *PolicyChunk) String() string { func (*PolicyChunk) ProtoMessage() {} func (x *PolicyChunk) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[140] + mi := &file_openshell_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10034,7 +10153,7 @@ func (x *PolicyChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyChunk.ProtoReflect.Descriptor instead. func (*PolicyChunk) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{140} + return file_openshell_proto_rawDescGZIP(), []int{142} } func (x *PolicyChunk) GetId() string { @@ -10180,7 +10299,7 @@ type DraftPolicyUpdate struct { func (x *DraftPolicyUpdate) Reset() { *x = DraftPolicyUpdate{} - mi := &file_openshell_proto_msgTypes[141] + mi := &file_openshell_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10192,7 +10311,7 @@ func (x *DraftPolicyUpdate) String() string { func (*DraftPolicyUpdate) ProtoMessage() {} func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[141] + mi := &file_openshell_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10205,7 +10324,7 @@ func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftPolicyUpdate.ProtoReflect.Descriptor instead. func (*DraftPolicyUpdate) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{141} + return file_openshell_proto_rawDescGZIP(), []int{143} } func (x *DraftPolicyUpdate) GetDraftVersion() uint64 { @@ -10263,7 +10382,7 @@ type SubmitPolicyAnalysisRequest struct { func (x *SubmitPolicyAnalysisRequest) Reset() { *x = SubmitPolicyAnalysisRequest{} - mi := &file_openshell_proto_msgTypes[142] + mi := &file_openshell_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10275,7 +10394,7 @@ func (x *SubmitPolicyAnalysisRequest) String() string { func (*SubmitPolicyAnalysisRequest) ProtoMessage() {} func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[142] + mi := &file_openshell_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10288,7 +10407,7 @@ func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisRequest.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{142} + return file_openshell_proto_rawDescGZIP(), []int{144} } func (x *SubmitPolicyAnalysisRequest) GetSummaries() []*DenialSummary { @@ -10351,7 +10470,7 @@ type SubmitPolicyAnalysisResponse struct { func (x *SubmitPolicyAnalysisResponse) Reset() { *x = SubmitPolicyAnalysisResponse{} - mi := &file_openshell_proto_msgTypes[143] + mi := &file_openshell_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10363,7 +10482,7 @@ func (x *SubmitPolicyAnalysisResponse) String() string { func (*SubmitPolicyAnalysisResponse) ProtoMessage() {} func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[143] + mi := &file_openshell_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10376,7 +10495,7 @@ func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisResponse.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{143} + return file_openshell_proto_rawDescGZIP(), []int{145} } func (x *SubmitPolicyAnalysisResponse) GetAcceptedChunks() uint32 { @@ -10422,7 +10541,7 @@ type GetDraftPolicyRequest struct { func (x *GetDraftPolicyRequest) Reset() { *x = GetDraftPolicyRequest{} - mi := &file_openshell_proto_msgTypes[144] + mi := &file_openshell_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10434,7 +10553,7 @@ func (x *GetDraftPolicyRequest) String() string { func (*GetDraftPolicyRequest) ProtoMessage() {} func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[144] + mi := &file_openshell_proto_msgTypes[146] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10447,7 +10566,7 @@ func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyRequest.ProtoReflect.Descriptor instead. func (*GetDraftPolicyRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{144} + return file_openshell_proto_rawDescGZIP(), []int{146} } func (x *GetDraftPolicyRequest) GetName() string { @@ -10487,7 +10606,7 @@ type GetDraftPolicyResponse struct { func (x *GetDraftPolicyResponse) Reset() { *x = GetDraftPolicyResponse{} - mi := &file_openshell_proto_msgTypes[145] + mi := &file_openshell_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10499,7 +10618,7 @@ func (x *GetDraftPolicyResponse) String() string { func (*GetDraftPolicyResponse) ProtoMessage() {} func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[145] + mi := &file_openshell_proto_msgTypes[147] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10512,7 +10631,7 @@ func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyResponse.ProtoReflect.Descriptor instead. func (*GetDraftPolicyResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{145} + return file_openshell_proto_rawDescGZIP(), []int{147} } func (x *GetDraftPolicyResponse) GetChunks() []*PolicyChunk { @@ -10558,7 +10677,7 @@ type ApproveDraftChunkRequest struct { func (x *ApproveDraftChunkRequest) Reset() { *x = ApproveDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[146] + mi := &file_openshell_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10570,7 +10689,7 @@ func (x *ApproveDraftChunkRequest) String() string { func (*ApproveDraftChunkRequest) ProtoMessage() {} func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[146] + mi := &file_openshell_proto_msgTypes[148] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10583,7 +10702,7 @@ func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkRequest.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{146} + return file_openshell_proto_rawDescGZIP(), []int{148} } func (x *ApproveDraftChunkRequest) GetName() string { @@ -10619,7 +10738,7 @@ type ApproveDraftChunkResponse struct { func (x *ApproveDraftChunkResponse) Reset() { *x = ApproveDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[147] + mi := &file_openshell_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10631,7 +10750,7 @@ func (x *ApproveDraftChunkResponse) String() string { func (*ApproveDraftChunkResponse) ProtoMessage() {} func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[147] + mi := &file_openshell_proto_msgTypes[149] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10644,7 +10763,7 @@ func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkResponse.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{147} + return file_openshell_proto_rawDescGZIP(), []int{149} } func (x *ApproveDraftChunkResponse) GetPolicyVersion() uint32 { @@ -10678,7 +10797,7 @@ type RejectDraftChunkRequest struct { func (x *RejectDraftChunkRequest) Reset() { *x = RejectDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[148] + mi := &file_openshell_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10690,7 +10809,7 @@ func (x *RejectDraftChunkRequest) String() string { func (*RejectDraftChunkRequest) ProtoMessage() {} func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[148] + mi := &file_openshell_proto_msgTypes[150] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10703,7 +10822,7 @@ func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkRequest.ProtoReflect.Descriptor instead. func (*RejectDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{148} + return file_openshell_proto_rawDescGZIP(), []int{150} } func (x *RejectDraftChunkRequest) GetName() string { @@ -10742,7 +10861,7 @@ type RejectDraftChunkResponse struct { func (x *RejectDraftChunkResponse) Reset() { *x = RejectDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[149] + mi := &file_openshell_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10754,7 +10873,7 @@ func (x *RejectDraftChunkResponse) String() string { func (*RejectDraftChunkResponse) ProtoMessage() {} func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[149] + mi := &file_openshell_proto_msgTypes[151] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10767,7 +10886,7 @@ func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkResponse.ProtoReflect.Descriptor instead. func (*RejectDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{149} + return file_openshell_proto_rawDescGZIP(), []int{151} } // Approve all pending chunks. @@ -10785,7 +10904,7 @@ type ApproveAllDraftChunksRequest struct { func (x *ApproveAllDraftChunksRequest) Reset() { *x = ApproveAllDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[150] + mi := &file_openshell_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10797,7 +10916,7 @@ func (x *ApproveAllDraftChunksRequest) String() string { func (*ApproveAllDraftChunksRequest) ProtoMessage() {} func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[150] + mi := &file_openshell_proto_msgTypes[152] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10810,7 +10929,7 @@ func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{150} + return file_openshell_proto_rawDescGZIP(), []int{152} } func (x *ApproveAllDraftChunksRequest) GetName() string { @@ -10850,7 +10969,7 @@ type ApproveAllDraftChunksResponse struct { func (x *ApproveAllDraftChunksResponse) Reset() { *x = ApproveAllDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[151] + mi := &file_openshell_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10862,7 +10981,7 @@ func (x *ApproveAllDraftChunksResponse) String() string { func (*ApproveAllDraftChunksResponse) ProtoMessage() {} func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[151] + mi := &file_openshell_proto_msgTypes[153] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10875,7 +10994,7 @@ func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{151} + return file_openshell_proto_rawDescGZIP(), []int{153} } func (x *ApproveAllDraftChunksResponse) GetPolicyVersion() uint32 { @@ -10923,7 +11042,7 @@ type EditDraftChunkRequest struct { func (x *EditDraftChunkRequest) Reset() { *x = EditDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[152] + mi := &file_openshell_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10935,7 +11054,7 @@ func (x *EditDraftChunkRequest) String() string { func (*EditDraftChunkRequest) ProtoMessage() {} func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[152] + mi := &file_openshell_proto_msgTypes[154] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10948,7 +11067,7 @@ func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkRequest.ProtoReflect.Descriptor instead. func (*EditDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{152} + return file_openshell_proto_rawDescGZIP(), []int{154} } func (x *EditDraftChunkRequest) GetName() string { @@ -10987,7 +11106,7 @@ type EditDraftChunkResponse struct { func (x *EditDraftChunkResponse) Reset() { *x = EditDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[153] + mi := &file_openshell_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10999,7 +11118,7 @@ func (x *EditDraftChunkResponse) String() string { func (*EditDraftChunkResponse) ProtoMessage() {} func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[153] + mi := &file_openshell_proto_msgTypes[155] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11012,7 +11131,7 @@ func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkResponse.ProtoReflect.Descriptor instead. func (*EditDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{153} + return file_openshell_proto_rawDescGZIP(), []int{155} } // Reverse an approval (remove merged rule from active policy). @@ -11030,7 +11149,7 @@ type UndoDraftChunkRequest struct { func (x *UndoDraftChunkRequest) Reset() { *x = UndoDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[154] + mi := &file_openshell_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11042,7 +11161,7 @@ func (x *UndoDraftChunkRequest) String() string { func (*UndoDraftChunkRequest) ProtoMessage() {} func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[154] + mi := &file_openshell_proto_msgTypes[156] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11055,7 +11174,7 @@ func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkRequest.ProtoReflect.Descriptor instead. func (*UndoDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{154} + return file_openshell_proto_rawDescGZIP(), []int{156} } func (x *UndoDraftChunkRequest) GetName() string { @@ -11091,7 +11210,7 @@ type UndoDraftChunkResponse struct { func (x *UndoDraftChunkResponse) Reset() { *x = UndoDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[155] + mi := &file_openshell_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11103,7 +11222,7 @@ func (x *UndoDraftChunkResponse) String() string { func (*UndoDraftChunkResponse) ProtoMessage() {} func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[155] + mi := &file_openshell_proto_msgTypes[157] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11116,7 +11235,7 @@ func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkResponse.ProtoReflect.Descriptor instead. func (*UndoDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{155} + return file_openshell_proto_rawDescGZIP(), []int{157} } func (x *UndoDraftChunkResponse) GetPolicyVersion() uint32 { @@ -11146,7 +11265,7 @@ type ClearDraftChunksRequest struct { func (x *ClearDraftChunksRequest) Reset() { *x = ClearDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[156] + mi := &file_openshell_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11158,7 +11277,7 @@ func (x *ClearDraftChunksRequest) String() string { func (*ClearDraftChunksRequest) ProtoMessage() {} func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[156] + mi := &file_openshell_proto_msgTypes[158] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11171,7 +11290,7 @@ func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ClearDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{156} + return file_openshell_proto_rawDescGZIP(), []int{158} } func (x *ClearDraftChunksRequest) GetName() string { @@ -11198,7 +11317,7 @@ type ClearDraftChunksResponse struct { func (x *ClearDraftChunksResponse) Reset() { *x = ClearDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[157] + mi := &file_openshell_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11210,7 +11329,7 @@ func (x *ClearDraftChunksResponse) String() string { func (*ClearDraftChunksResponse) ProtoMessage() {} func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[157] + mi := &file_openshell_proto_msgTypes[159] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11223,7 +11342,7 @@ func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ClearDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{157} + return file_openshell_proto_rawDescGZIP(), []int{159} } func (x *ClearDraftChunksResponse) GetChunksCleared() uint32 { @@ -11246,7 +11365,7 @@ type GetDraftHistoryRequest struct { func (x *GetDraftHistoryRequest) Reset() { *x = GetDraftHistoryRequest{} - mi := &file_openshell_proto_msgTypes[158] + mi := &file_openshell_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11258,7 +11377,7 @@ func (x *GetDraftHistoryRequest) String() string { func (*GetDraftHistoryRequest) ProtoMessage() {} func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[158] + mi := &file_openshell_proto_msgTypes[160] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11271,7 +11390,7 @@ func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryRequest.ProtoReflect.Descriptor instead. func (*GetDraftHistoryRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{158} + return file_openshell_proto_rawDescGZIP(), []int{160} } func (x *GetDraftHistoryRequest) GetName() string { @@ -11305,7 +11424,7 @@ type DraftHistoryEntry struct { func (x *DraftHistoryEntry) Reset() { *x = DraftHistoryEntry{} - mi := &file_openshell_proto_msgTypes[159] + mi := &file_openshell_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11317,7 +11436,7 @@ func (x *DraftHistoryEntry) String() string { func (*DraftHistoryEntry) ProtoMessage() {} func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[159] + mi := &file_openshell_proto_msgTypes[161] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11330,7 +11449,7 @@ func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftHistoryEntry.ProtoReflect.Descriptor instead. func (*DraftHistoryEntry) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{159} + return file_openshell_proto_rawDescGZIP(), []int{161} } func (x *DraftHistoryEntry) GetTimestampMs() int64 { @@ -11371,7 +11490,7 @@ type GetDraftHistoryResponse struct { func (x *GetDraftHistoryResponse) Reset() { *x = GetDraftHistoryResponse{} - mi := &file_openshell_proto_msgTypes[160] + mi := &file_openshell_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11383,7 +11502,7 @@ func (x *GetDraftHistoryResponse) String() string { func (*GetDraftHistoryResponse) ProtoMessage() {} func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[160] + mi := &file_openshell_proto_msgTypes[162] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11396,7 +11515,7 @@ func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryResponse.ProtoReflect.Descriptor instead. func (*GetDraftHistoryResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{160} + return file_openshell_proto_rawDescGZIP(), []int{162} } func (x *GetDraftHistoryResponse) GetEntries() []*DraftHistoryEntry { @@ -11425,7 +11544,7 @@ type PolicyRevisionPayload struct { func (x *PolicyRevisionPayload) Reset() { *x = PolicyRevisionPayload{} - mi := &file_openshell_proto_msgTypes[161] + mi := &file_openshell_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11437,7 +11556,7 @@ func (x *PolicyRevisionPayload) String() string { func (*PolicyRevisionPayload) ProtoMessage() {} func (x *PolicyRevisionPayload) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[161] + mi := &file_openshell_proto_msgTypes[163] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11450,7 +11569,7 @@ func (x *PolicyRevisionPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyRevisionPayload.ProtoReflect.Descriptor instead. func (*PolicyRevisionPayload) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{161} + return file_openshell_proto_rawDescGZIP(), []int{163} } func (x *PolicyRevisionPayload) GetPolicy() *sandboxv1.SandboxPolicy { @@ -11523,7 +11642,7 @@ type DraftChunkPayload struct { func (x *DraftChunkPayload) Reset() { *x = DraftChunkPayload{} - mi := &file_openshell_proto_msgTypes[162] + mi := &file_openshell_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11535,7 +11654,7 @@ func (x *DraftChunkPayload) String() string { func (*DraftChunkPayload) ProtoMessage() {} func (x *DraftChunkPayload) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[162] + mi := &file_openshell_proto_msgTypes[164] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11548,7 +11667,7 @@ func (x *DraftChunkPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftChunkPayload.ProtoReflect.Descriptor instead. func (*DraftChunkPayload) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{162} + return file_openshell_proto_rawDescGZIP(), []int{164} } func (x *DraftChunkPayload) GetRuleName() string { @@ -11654,7 +11773,7 @@ type StoredPolicyRevision struct { func (x *StoredPolicyRevision) Reset() { *x = StoredPolicyRevision{} - mi := &file_openshell_proto_msgTypes[163] + mi := &file_openshell_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11666,7 +11785,7 @@ func (x *StoredPolicyRevision) String() string { func (*StoredPolicyRevision) ProtoMessage() {} func (x *StoredPolicyRevision) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[163] + mi := &file_openshell_proto_msgTypes[165] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11679,7 +11798,7 @@ func (x *StoredPolicyRevision) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredPolicyRevision.ProtoReflect.Descriptor instead. func (*StoredPolicyRevision) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{163} + return file_openshell_proto_rawDescGZIP(), []int{165} } func (x *StoredPolicyRevision) GetId() string { @@ -11782,7 +11901,7 @@ type StoredDraftChunk struct { func (x *StoredDraftChunk) Reset() { *x = StoredDraftChunk{} - mi := &file_openshell_proto_msgTypes[164] + mi := &file_openshell_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11794,7 +11913,7 @@ func (x *StoredDraftChunk) String() string { func (*StoredDraftChunk) ProtoMessage() {} func (x *StoredDraftChunk) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[164] + mi := &file_openshell_proto_msgTypes[166] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11807,7 +11926,7 @@ func (x *StoredDraftChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredDraftChunk.ProtoReflect.Descriptor instead. func (*StoredDraftChunk) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{164} + return file_openshell_proto_rawDescGZIP(), []int{166} } func (x *StoredDraftChunk) GetId() string { @@ -11956,7 +12075,7 @@ type CreateWorkspaceRequest struct { func (x *CreateWorkspaceRequest) Reset() { *x = CreateWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[165] + mi := &file_openshell_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11968,7 +12087,7 @@ func (x *CreateWorkspaceRequest) String() string { func (*CreateWorkspaceRequest) ProtoMessage() {} func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[165] + mi := &file_openshell_proto_msgTypes[167] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11981,7 +12100,7 @@ func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceRequest.ProtoReflect.Descriptor instead. func (*CreateWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{165} + return file_openshell_proto_rawDescGZIP(), []int{167} } func (x *CreateWorkspaceRequest) GetName() string { @@ -12008,7 +12127,7 @@ type CreateWorkspaceResponse struct { func (x *CreateWorkspaceResponse) Reset() { *x = CreateWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[166] + mi := &file_openshell_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12020,7 +12139,7 @@ func (x *CreateWorkspaceResponse) String() string { func (*CreateWorkspaceResponse) ProtoMessage() {} func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[166] + mi := &file_openshell_proto_msgTypes[168] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12033,7 +12152,7 @@ func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceResponse.ProtoReflect.Descriptor instead. func (*CreateWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{166} + return file_openshell_proto_rawDescGZIP(), []int{168} } func (x *CreateWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -12054,7 +12173,7 @@ type GetWorkspaceRequest struct { func (x *GetWorkspaceRequest) Reset() { *x = GetWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[167] + mi := &file_openshell_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12066,7 +12185,7 @@ func (x *GetWorkspaceRequest) String() string { func (*GetWorkspaceRequest) ProtoMessage() {} func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[167] + mi := &file_openshell_proto_msgTypes[169] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12079,7 +12198,7 @@ func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceRequest.ProtoReflect.Descriptor instead. func (*GetWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{167} + return file_openshell_proto_rawDescGZIP(), []int{169} } func (x *GetWorkspaceRequest) GetName() string { @@ -12099,7 +12218,7 @@ type GetWorkspaceResponse struct { func (x *GetWorkspaceResponse) Reset() { *x = GetWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[168] + mi := &file_openshell_proto_msgTypes[170] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12111,7 +12230,7 @@ func (x *GetWorkspaceResponse) String() string { func (*GetWorkspaceResponse) ProtoMessage() {} func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[168] + mi := &file_openshell_proto_msgTypes[170] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12124,7 +12243,7 @@ func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceResponse.ProtoReflect.Descriptor instead. func (*GetWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{168} + return file_openshell_proto_rawDescGZIP(), []int{170} } func (x *GetWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -12147,7 +12266,7 @@ type ListWorkspacesRequest struct { func (x *ListWorkspacesRequest) Reset() { *x = ListWorkspacesRequest{} - mi := &file_openshell_proto_msgTypes[169] + mi := &file_openshell_proto_msgTypes[171] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12159,7 +12278,7 @@ func (x *ListWorkspacesRequest) String() string { func (*ListWorkspacesRequest) ProtoMessage() {} func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[169] + mi := &file_openshell_proto_msgTypes[171] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12172,7 +12291,7 @@ func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesRequest.ProtoReflect.Descriptor instead. func (*ListWorkspacesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{169} + return file_openshell_proto_rawDescGZIP(), []int{171} } func (x *ListWorkspacesRequest) GetLimit() uint32 { @@ -12206,7 +12325,7 @@ type ListWorkspacesResponse struct { func (x *ListWorkspacesResponse) Reset() { *x = ListWorkspacesResponse{} - mi := &file_openshell_proto_msgTypes[170] + mi := &file_openshell_proto_msgTypes[172] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12218,7 +12337,7 @@ func (x *ListWorkspacesResponse) String() string { func (*ListWorkspacesResponse) ProtoMessage() {} func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[170] + mi := &file_openshell_proto_msgTypes[172] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12231,7 +12350,7 @@ func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesResponse.ProtoReflect.Descriptor instead. func (*ListWorkspacesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{170} + return file_openshell_proto_rawDescGZIP(), []int{172} } func (x *ListWorkspacesResponse) GetWorkspaces() []*datamodelv1.Workspace { @@ -12252,7 +12371,7 @@ type DeleteWorkspaceRequest struct { func (x *DeleteWorkspaceRequest) Reset() { *x = DeleteWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[173] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12264,7 +12383,7 @@ func (x *DeleteWorkspaceRequest) String() string { func (*DeleteWorkspaceRequest) ProtoMessage() {} func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[173] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12277,7 +12396,7 @@ func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{171} + return file_openshell_proto_rawDescGZIP(), []int{173} } func (x *DeleteWorkspaceRequest) GetName() string { @@ -12297,7 +12416,7 @@ type DeleteWorkspaceResponse struct { func (x *DeleteWorkspaceResponse) Reset() { *x = DeleteWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[174] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12309,7 +12428,7 @@ func (x *DeleteWorkspaceResponse) String() string { func (*DeleteWorkspaceResponse) ProtoMessage() {} func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[174] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12322,7 +12441,7 @@ func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceResponse.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{172} + return file_openshell_proto_rawDescGZIP(), []int{174} } func (x *DeleteWorkspaceResponse) GetDeleted() bool { @@ -12346,7 +12465,7 @@ type WorkspaceMember struct { func (x *WorkspaceMember) Reset() { *x = WorkspaceMember{} - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[175] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12358,7 +12477,7 @@ func (x *WorkspaceMember) String() string { func (*WorkspaceMember) ProtoMessage() {} func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[175] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12371,7 +12490,7 @@ func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkspaceMember.ProtoReflect.Descriptor instead. func (*WorkspaceMember) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{173} + return file_openshell_proto_rawDescGZIP(), []int{175} } func (x *WorkspaceMember) GetMetadata() *datamodelv1.ObjectMeta { @@ -12410,7 +12529,7 @@ type AddWorkspaceMemberRequest struct { func (x *AddWorkspaceMemberRequest) Reset() { *x = AddWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[176] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12422,7 +12541,7 @@ func (x *AddWorkspaceMemberRequest) String() string { func (*AddWorkspaceMemberRequest) ProtoMessage() {} func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[176] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12435,7 +12554,7 @@ func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{174} + return file_openshell_proto_rawDescGZIP(), []int{176} } func (x *AddWorkspaceMemberRequest) GetWorkspace() string { @@ -12469,7 +12588,7 @@ type AddWorkspaceMemberResponse struct { func (x *AddWorkspaceMemberResponse) Reset() { *x = AddWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[177] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12481,7 +12600,7 @@ func (x *AddWorkspaceMemberResponse) String() string { func (*AddWorkspaceMemberResponse) ProtoMessage() {} func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[177] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12494,7 +12613,7 @@ func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{175} + return file_openshell_proto_rawDescGZIP(), []int{177} } func (x *AddWorkspaceMemberResponse) GetMember() *WorkspaceMember { @@ -12517,7 +12636,7 @@ type RemoveWorkspaceMemberRequest struct { func (x *RemoveWorkspaceMemberRequest) Reset() { *x = RemoveWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[178] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12529,7 +12648,7 @@ func (x *RemoveWorkspaceMemberRequest) String() string { func (*RemoveWorkspaceMemberRequest) ProtoMessage() {} func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[178] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12542,7 +12661,7 @@ func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{176} + return file_openshell_proto_rawDescGZIP(), []int{178} } func (x *RemoveWorkspaceMemberRequest) GetWorkspace() string { @@ -12569,7 +12688,7 @@ type RemoveWorkspaceMemberResponse struct { func (x *RemoveWorkspaceMemberResponse) Reset() { *x = RemoveWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[179] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12581,7 +12700,7 @@ func (x *RemoveWorkspaceMemberResponse) String() string { func (*RemoveWorkspaceMemberResponse) ProtoMessage() {} func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[179] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12594,7 +12713,7 @@ func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{177} + return file_openshell_proto_rawDescGZIP(), []int{179} } func (x *RemoveWorkspaceMemberResponse) GetRemoved() bool { @@ -12617,7 +12736,7 @@ type ListWorkspaceMembersRequest struct { func (x *ListWorkspaceMembersRequest) Reset() { *x = ListWorkspaceMembersRequest{} - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[180] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12629,7 +12748,7 @@ func (x *ListWorkspaceMembersRequest) String() string { func (*ListWorkspaceMembersRequest) ProtoMessage() {} func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[180] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12642,7 +12761,7 @@ func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersRequest.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{178} + return file_openshell_proto_rawDescGZIP(), []int{180} } func (x *ListWorkspaceMembersRequest) GetWorkspace() string { @@ -12676,7 +12795,7 @@ type ListWorkspaceMembersResponse struct { func (x *ListWorkspaceMembersResponse) Reset() { *x = ListWorkspaceMembersResponse{} - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[181] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12688,7 +12807,7 @@ func (x *ListWorkspaceMembersResponse) String() string { func (*ListWorkspaceMembersResponse) ProtoMessage() {} func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[181] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12701,7 +12820,7 @@ func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersResponse.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{179} + return file_openshell_proto_rawDescGZIP(), []int{181} } func (x *ListWorkspaceMembersResponse) GetMembers() []*WorkspaceMember { @@ -12853,6 +12972,12 @@ const file_openshell_proto_rawDesc = "" + "\tworkspace\x18\x04 \x01(\tR\tworkspace\"H\n" + "\x14DeleteSandboxRequest\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" + + "\tworkspace\x18\x02 \x01(\tR\tworkspace\"I\n" + + "\x15SuspendSandboxRequest\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" + + "\tworkspace\x18\x02 \x01(\tR\tworkspace\"H\n" + + "\x14ResumeSandboxRequest\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" + "\tworkspace\x18\x02 \x01(\tR\tworkspace\"B\n" + "\x0fSandboxResponse\x12/\n" + "\asandbox\x18\x01 \x01(\v2\x15.openshell.v1.SandboxR\asandbox\"L\n" + @@ -13683,14 +13808,17 @@ const file_openshell_proto_rawDesc = "" + "\x05limit\x18\x02 \x01(\rR\x05limit\x12\x16\n" + "\x06offset\x18\x03 \x01(\rR\x06offset\"W\n" + "\x1cListWorkspaceMembersResponse\x127\n" + - "\amembers\x18\x01 \x03(\v2\x1d.openshell.v1.WorkspaceMemberR\amembers*\xb6\x01\n" + + "\amembers\x18\x01 \x03(\v2\x1d.openshell.v1.WorkspaceMemberR\amembers*\x8d\x02\n" + "\fSandboxPhase\x12\x1d\n" + "\x19SANDBOX_PHASE_UNSPECIFIED\x10\x00\x12\x1e\n" + "\x1aSANDBOX_PHASE_PROVISIONING\x10\x01\x12\x17\n" + "\x13SANDBOX_PHASE_READY\x10\x02\x12\x17\n" + "\x13SANDBOX_PHASE_ERROR\x10\x03\x12\x1a\n" + "\x16SANDBOX_PHASE_DELETING\x10\x04\x12\x19\n" + - "\x15SANDBOX_PHASE_UNKNOWN\x10\x05*\xc3\x03\n" + + "\x15SANDBOX_PHASE_UNKNOWN\x10\x05\x12\x1c\n" + + "\x18SANDBOX_PHASE_SUSPENDING\x10\x06\x12\x1b\n" + + "\x17SANDBOX_PHASE_SUSPENDED\x10\a\x12\x1a\n" + + "\x16SANDBOX_PHASE_RESUMING\x10\b*\xc3\x03\n" + "!ProviderCredentialRefreshStrategy\x124\n" + "0PROVIDER_CREDENTIAL_REFRESH_STRATEGY_UNSPECIFIED\x10\x00\x12/\n" + "+PROVIDER_CREDENTIAL_REFRESH_STRATEGY_STATIC\x10\x01\x121\n" + @@ -13722,7 +13850,7 @@ const file_openshell_proto_rawDesc = "" + "\rWorkspaceRole\x12\x1e\n" + "\x1aWORKSPACE_ROLE_UNSPECIFIED\x10\x00\x12\x17\n" + "\x13WORKSPACE_ROLE_USER\x10\x01\x12\x18\n" + - "\x14WORKSPACE_ROLE_ADMIN\x10\x022\xacB\n" + + "\x14WORKSPACE_ROLE_ADMIN\x10\x022\x9cD\n" + "\tOpenShell\x12Z\n" + "\x06Health\x12\x1b.openshell.v1.HealthRequest\x1a\x1c.openshell.v1.HealthResponse\"\x15\x82\xb5\x18\x11\n" + "\x0funauthenticated\x12i\n" + @@ -13744,6 +13872,10 @@ const file_openshell_proto_rawDesc = "" + "\x15DetachSandboxProvider\x12*.openshell.v1.DetachSandboxProviderRequest\x1a+.openshell.v1.DetachSandboxProviderResponse\"!\x82\xb5\x18\x1d\n" + "\x06bearer\x12\x04user\"\rsandbox:write\x12{\n" + "\rDeleteSandbox\x12\".openshell.v1.DeleteSandboxRequest\x1a#.openshell.v1.DeleteSandboxResponse\"!\x82\xb5\x18\x1d\n" + + "\x06bearer\x12\x04user\"\rsandbox:write\x12w\n" + + "\x0eSuspendSandbox\x12#.openshell.v1.SuspendSandboxRequest\x1a\x1d.openshell.v1.SandboxResponse\"!\x82\xb5\x18\x1d\n" + + "\x06bearer\x12\x04user\"\rsandbox:write\x12u\n" + + "\rResumeSandbox\x12\".openshell.v1.ResumeSandboxRequest\x1a\x1d.openshell.v1.SandboxResponse\"!\x82\xb5\x18\x1d\n" + "\x06bearer\x12\x04user\"\rsandbox:write\x12\x84\x01\n" + "\x10CreateSshSession\x12%.openshell.v1.CreateSshSessionRequest\x1a&.openshell.v1.CreateSshSessionResponse\"!\x82\xb5\x18\x1d\n" + "\x06bearer\x12\x04user\"\rsandbox:write\x12}\n" + @@ -13869,7 +14001,7 @@ func file_openshell_proto_rawDescGZIP() []byte { } var file_openshell_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 203) +var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 205) var file_openshell_proto_goTypes = []any{ (SandboxPhase)(0), // 0: openshell.v1.SandboxPhase (ProviderCredentialRefreshStrategy)(0), // 1: openshell.v1.ProviderCredentialRefreshStrategy @@ -13904,346 +14036,348 @@ var file_openshell_proto_goTypes = []any{ (*AttachSandboxProviderRequest)(nil), // 30: openshell.v1.AttachSandboxProviderRequest (*DetachSandboxProviderRequest)(nil), // 31: openshell.v1.DetachSandboxProviderRequest (*DeleteSandboxRequest)(nil), // 32: openshell.v1.DeleteSandboxRequest - (*SandboxResponse)(nil), // 33: openshell.v1.SandboxResponse - (*ListSandboxesResponse)(nil), // 34: openshell.v1.ListSandboxesResponse - (*ListSandboxProvidersResponse)(nil), // 35: openshell.v1.ListSandboxProvidersResponse - (*AttachSandboxProviderResponse)(nil), // 36: openshell.v1.AttachSandboxProviderResponse - (*DetachSandboxProviderResponse)(nil), // 37: openshell.v1.DetachSandboxProviderResponse - (*DeleteSandboxResponse)(nil), // 38: openshell.v1.DeleteSandboxResponse - (*CreateSshSessionRequest)(nil), // 39: openshell.v1.CreateSshSessionRequest - (*CreateSshSessionResponse)(nil), // 40: openshell.v1.CreateSshSessionResponse - (*ExposeServiceRequest)(nil), // 41: openshell.v1.ExposeServiceRequest - (*GetServiceRequest)(nil), // 42: openshell.v1.GetServiceRequest - (*ListServicesRequest)(nil), // 43: openshell.v1.ListServicesRequest - (*ListServicesResponse)(nil), // 44: openshell.v1.ListServicesResponse - (*DeleteServiceRequest)(nil), // 45: openshell.v1.DeleteServiceRequest - (*DeleteServiceResponse)(nil), // 46: openshell.v1.DeleteServiceResponse - (*ServiceEndpoint)(nil), // 47: openshell.v1.ServiceEndpoint - (*ServiceEndpointResponse)(nil), // 48: openshell.v1.ServiceEndpointResponse - (*RevokeSshSessionRequest)(nil), // 49: openshell.v1.RevokeSshSessionRequest - (*RevokeSshSessionResponse)(nil), // 50: openshell.v1.RevokeSshSessionResponse - (*ExecSandboxRequest)(nil), // 51: openshell.v1.ExecSandboxRequest - (*ExecSandboxStdout)(nil), // 52: openshell.v1.ExecSandboxStdout - (*ExecSandboxStderr)(nil), // 53: openshell.v1.ExecSandboxStderr - (*ExecSandboxExit)(nil), // 54: openshell.v1.ExecSandboxExit - (*ExecSandboxEvent)(nil), // 55: openshell.v1.ExecSandboxEvent - (*TcpForwardInit)(nil), // 56: openshell.v1.TcpForwardInit - (*TcpForwardFrame)(nil), // 57: openshell.v1.TcpForwardFrame - (*ExecSandboxInput)(nil), // 58: openshell.v1.ExecSandboxInput - (*ExecSandboxWindowResize)(nil), // 59: openshell.v1.ExecSandboxWindowResize - (*SshSession)(nil), // 60: openshell.v1.SshSession - (*WatchSandboxRequest)(nil), // 61: openshell.v1.WatchSandboxRequest - (*SandboxStreamEvent)(nil), // 62: openshell.v1.SandboxStreamEvent - (*SandboxLogLine)(nil), // 63: openshell.v1.SandboxLogLine - (*SandboxStreamWarning)(nil), // 64: openshell.v1.SandboxStreamWarning - (*CreateProviderRequest)(nil), // 65: openshell.v1.CreateProviderRequest - (*GetProviderRequest)(nil), // 66: openshell.v1.GetProviderRequest - (*ListProvidersRequest)(nil), // 67: openshell.v1.ListProvidersRequest - (*UpdateProviderRequest)(nil), // 68: openshell.v1.UpdateProviderRequest - (*DeleteProviderRequest)(nil), // 69: openshell.v1.DeleteProviderRequest - (*ProviderResponse)(nil), // 70: openshell.v1.ProviderResponse - (*ListProvidersResponse)(nil), // 71: openshell.v1.ListProvidersResponse - (*ListProviderProfilesRequest)(nil), // 72: openshell.v1.ListProviderProfilesRequest - (*GetProviderProfileRequest)(nil), // 73: openshell.v1.GetProviderProfileRequest - (*ProviderProfileImportItem)(nil), // 74: openshell.v1.ProviderProfileImportItem - (*ProviderProfileDiagnostic)(nil), // 75: openshell.v1.ProviderProfileDiagnostic - (*ProviderCredentialTokenGrantAudienceOverride)(nil), // 76: openshell.v1.ProviderCredentialTokenGrantAudienceOverride - (*ProviderCredentialTokenGrant)(nil), // 77: openshell.v1.ProviderCredentialTokenGrant - (*ProviderProfileCredential)(nil), // 78: openshell.v1.ProviderProfileCredential - (*ProviderCredentialRefreshMaterial)(nil), // 79: openshell.v1.ProviderCredentialRefreshMaterial - (*ProviderCredentialRefreshOutput)(nil), // 80: openshell.v1.ProviderCredentialRefreshOutput - (*ProviderCredentialRefresh)(nil), // 81: openshell.v1.ProviderCredentialRefresh - (*ProviderCredentialRefreshStatus)(nil), // 82: openshell.v1.ProviderCredentialRefreshStatus - (*ProviderProfileDiscovery)(nil), // 83: openshell.v1.ProviderProfileDiscovery - (*StoredProviderCredentialRefreshState)(nil), // 84: openshell.v1.StoredProviderCredentialRefreshState - (*GetProviderRefreshStatusRequest)(nil), // 85: openshell.v1.GetProviderRefreshStatusRequest - (*GetProviderRefreshStatusResponse)(nil), // 86: openshell.v1.GetProviderRefreshStatusResponse - (*ConfigureProviderRefreshRequest)(nil), // 87: openshell.v1.ConfigureProviderRefreshRequest - (*ConfigureProviderRefreshResponse)(nil), // 88: openshell.v1.ConfigureProviderRefreshResponse - (*RotateProviderCredentialRequest)(nil), // 89: openshell.v1.RotateProviderCredentialRequest - (*RotateProviderCredentialResponse)(nil), // 90: openshell.v1.RotateProviderCredentialResponse - (*DeleteProviderRefreshRequest)(nil), // 91: openshell.v1.DeleteProviderRefreshRequest - (*DeleteProviderRefreshResponse)(nil), // 92: openshell.v1.DeleteProviderRefreshResponse - (*ProviderProfile)(nil), // 93: openshell.v1.ProviderProfile - (*StoredProviderProfile)(nil), // 94: openshell.v1.StoredProviderProfile - (*ProviderProfileResponse)(nil), // 95: openshell.v1.ProviderProfileResponse - (*ListProviderProfilesResponse)(nil), // 96: openshell.v1.ListProviderProfilesResponse - (*ImportProviderProfilesRequest)(nil), // 97: openshell.v1.ImportProviderProfilesRequest - (*ImportProviderProfilesResponse)(nil), // 98: openshell.v1.ImportProviderProfilesResponse - (*UpdateProviderProfilesRequest)(nil), // 99: openshell.v1.UpdateProviderProfilesRequest - (*UpdateProviderProfilesResponse)(nil), // 100: openshell.v1.UpdateProviderProfilesResponse - (*LintProviderProfilesRequest)(nil), // 101: openshell.v1.LintProviderProfilesRequest - (*LintProviderProfilesResponse)(nil), // 102: openshell.v1.LintProviderProfilesResponse - (*DeleteProviderResponse)(nil), // 103: openshell.v1.DeleteProviderResponse - (*DeleteProviderProfileRequest)(nil), // 104: openshell.v1.DeleteProviderProfileRequest - (*DeleteProviderProfileResponse)(nil), // 105: openshell.v1.DeleteProviderProfileResponse - (*GetSandboxProviderEnvironmentRequest)(nil), // 106: openshell.v1.GetSandboxProviderEnvironmentRequest - (*GetSandboxProviderEnvironmentResponse)(nil), // 107: openshell.v1.GetSandboxProviderEnvironmentResponse - (*UpdateConfigRequest)(nil), // 108: openshell.v1.UpdateConfigRequest - (*PolicyMergeOperation)(nil), // 109: openshell.v1.PolicyMergeOperation - (*AddNetworkRule)(nil), // 110: openshell.v1.AddNetworkRule - (*RemoveNetworkEndpoint)(nil), // 111: openshell.v1.RemoveNetworkEndpoint - (*RemoveNetworkRule)(nil), // 112: openshell.v1.RemoveNetworkRule - (*AddDenyRules)(nil), // 113: openshell.v1.AddDenyRules - (*AddAllowRules)(nil), // 114: openshell.v1.AddAllowRules - (*RemoveNetworkBinary)(nil), // 115: openshell.v1.RemoveNetworkBinary - (*UpdateConfigResponse)(nil), // 116: openshell.v1.UpdateConfigResponse - (*GetSandboxPolicyStatusRequest)(nil), // 117: openshell.v1.GetSandboxPolicyStatusRequest - (*GetSandboxPolicyStatusResponse)(nil), // 118: openshell.v1.GetSandboxPolicyStatusResponse - (*ListSandboxPoliciesRequest)(nil), // 119: openshell.v1.ListSandboxPoliciesRequest - (*ListSandboxPoliciesResponse)(nil), // 120: openshell.v1.ListSandboxPoliciesResponse - (*ReportPolicyStatusRequest)(nil), // 121: openshell.v1.ReportPolicyStatusRequest - (*ReportPolicyStatusResponse)(nil), // 122: openshell.v1.ReportPolicyStatusResponse - (*SandboxPolicyRevision)(nil), // 123: openshell.v1.SandboxPolicyRevision - (*GetSandboxLogsRequest)(nil), // 124: openshell.v1.GetSandboxLogsRequest - (*PushSandboxLogsRequest)(nil), // 125: openshell.v1.PushSandboxLogsRequest - (*PushSandboxLogsResponse)(nil), // 126: openshell.v1.PushSandboxLogsResponse - (*GetSandboxLogsResponse)(nil), // 127: openshell.v1.GetSandboxLogsResponse - (*SupervisorMessage)(nil), // 128: openshell.v1.SupervisorMessage - (*GatewayMessage)(nil), // 129: openshell.v1.GatewayMessage - (*SupervisorHello)(nil), // 130: openshell.v1.SupervisorHello - (*SessionAccepted)(nil), // 131: openshell.v1.SessionAccepted - (*SessionRejected)(nil), // 132: openshell.v1.SessionRejected - (*SupervisorHeartbeat)(nil), // 133: openshell.v1.SupervisorHeartbeat - (*GatewayHeartbeat)(nil), // 134: openshell.v1.GatewayHeartbeat - (*RelayOpen)(nil), // 135: openshell.v1.RelayOpen - (*SshRelayTarget)(nil), // 136: openshell.v1.SshRelayTarget - (*TcpRelayTarget)(nil), // 137: openshell.v1.TcpRelayTarget - (*RelayInit)(nil), // 138: openshell.v1.RelayInit - (*RelayFrame)(nil), // 139: openshell.v1.RelayFrame - (*RelayOpenResult)(nil), // 140: openshell.v1.RelayOpenResult - (*RelayClose)(nil), // 141: openshell.v1.RelayClose - (*L7RequestSample)(nil), // 142: openshell.v1.L7RequestSample - (*DenialSummary)(nil), // 143: openshell.v1.DenialSummary - (*DenialGroupCount)(nil), // 144: openshell.v1.DenialGroupCount - (*NetworkActivitySummary)(nil), // 145: openshell.v1.NetworkActivitySummary - (*PolicyChunk)(nil), // 146: openshell.v1.PolicyChunk - (*DraftPolicyUpdate)(nil), // 147: openshell.v1.DraftPolicyUpdate - (*SubmitPolicyAnalysisRequest)(nil), // 148: openshell.v1.SubmitPolicyAnalysisRequest - (*SubmitPolicyAnalysisResponse)(nil), // 149: openshell.v1.SubmitPolicyAnalysisResponse - (*GetDraftPolicyRequest)(nil), // 150: openshell.v1.GetDraftPolicyRequest - (*GetDraftPolicyResponse)(nil), // 151: openshell.v1.GetDraftPolicyResponse - (*ApproveDraftChunkRequest)(nil), // 152: openshell.v1.ApproveDraftChunkRequest - (*ApproveDraftChunkResponse)(nil), // 153: openshell.v1.ApproveDraftChunkResponse - (*RejectDraftChunkRequest)(nil), // 154: openshell.v1.RejectDraftChunkRequest - (*RejectDraftChunkResponse)(nil), // 155: openshell.v1.RejectDraftChunkResponse - (*ApproveAllDraftChunksRequest)(nil), // 156: openshell.v1.ApproveAllDraftChunksRequest - (*ApproveAllDraftChunksResponse)(nil), // 157: openshell.v1.ApproveAllDraftChunksResponse - (*EditDraftChunkRequest)(nil), // 158: openshell.v1.EditDraftChunkRequest - (*EditDraftChunkResponse)(nil), // 159: openshell.v1.EditDraftChunkResponse - (*UndoDraftChunkRequest)(nil), // 160: openshell.v1.UndoDraftChunkRequest - (*UndoDraftChunkResponse)(nil), // 161: openshell.v1.UndoDraftChunkResponse - (*ClearDraftChunksRequest)(nil), // 162: openshell.v1.ClearDraftChunksRequest - (*ClearDraftChunksResponse)(nil), // 163: openshell.v1.ClearDraftChunksResponse - (*GetDraftHistoryRequest)(nil), // 164: openshell.v1.GetDraftHistoryRequest - (*DraftHistoryEntry)(nil), // 165: openshell.v1.DraftHistoryEntry - (*GetDraftHistoryResponse)(nil), // 166: openshell.v1.GetDraftHistoryResponse - (*PolicyRevisionPayload)(nil), // 167: openshell.v1.PolicyRevisionPayload - (*DraftChunkPayload)(nil), // 168: openshell.v1.DraftChunkPayload - (*StoredPolicyRevision)(nil), // 169: openshell.v1.StoredPolicyRevision - (*StoredDraftChunk)(nil), // 170: openshell.v1.StoredDraftChunk - (*CreateWorkspaceRequest)(nil), // 171: openshell.v1.CreateWorkspaceRequest - (*CreateWorkspaceResponse)(nil), // 172: openshell.v1.CreateWorkspaceResponse - (*GetWorkspaceRequest)(nil), // 173: openshell.v1.GetWorkspaceRequest - (*GetWorkspaceResponse)(nil), // 174: openshell.v1.GetWorkspaceResponse - (*ListWorkspacesRequest)(nil), // 175: openshell.v1.ListWorkspacesRequest - (*ListWorkspacesResponse)(nil), // 176: openshell.v1.ListWorkspacesResponse - (*DeleteWorkspaceRequest)(nil), // 177: openshell.v1.DeleteWorkspaceRequest - (*DeleteWorkspaceResponse)(nil), // 178: openshell.v1.DeleteWorkspaceResponse - (*WorkspaceMember)(nil), // 179: openshell.v1.WorkspaceMember - (*AddWorkspaceMemberRequest)(nil), // 180: openshell.v1.AddWorkspaceMemberRequest - (*AddWorkspaceMemberResponse)(nil), // 181: openshell.v1.AddWorkspaceMemberResponse - (*RemoveWorkspaceMemberRequest)(nil), // 182: openshell.v1.RemoveWorkspaceMemberRequest - (*RemoveWorkspaceMemberResponse)(nil), // 183: openshell.v1.RemoveWorkspaceMemberResponse - (*ListWorkspaceMembersRequest)(nil), // 184: openshell.v1.ListWorkspaceMembersRequest - (*ListWorkspaceMembersResponse)(nil), // 185: openshell.v1.ListWorkspaceMembersResponse - nil, // 186: openshell.v1.SandboxSpec.EnvironmentEntry - nil, // 187: openshell.v1.SandboxTemplate.LabelsEntry - nil, // 188: openshell.v1.SandboxTemplate.AnnotationsEntry - nil, // 189: openshell.v1.SandboxTemplate.EnvironmentEntry - nil, // 190: openshell.v1.PlatformEvent.MetadataEntry - nil, // 191: openshell.v1.CreateSandboxRequest.LabelsEntry - nil, // 192: openshell.v1.CreateSandboxRequest.AnnotationsEntry - nil, // 193: openshell.v1.ExecSandboxRequest.EnvironmentEntry - nil, // 194: openshell.v1.SandboxLogLine.FieldsEntry - nil, // 195: openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry - nil, // 196: openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry - nil, // 197: openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - nil, // 198: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - nil, // 199: openshell.v1.ProviderProfile.AnnotationsEntry - nil, // 200: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - nil, // 201: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry - nil, // 202: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - nil, // 203: openshell.v1.UpdateConfigRequest.AnnotationsEntry - nil, // 204: openshell.v1.UpdateConfigResponse.AnnotationsEntry - nil, // 205: openshell.v1.SandboxPolicyRevision.ProvenanceEntry - nil, // 206: openshell.v1.PolicyRevisionPayload.ProvenanceEntry - nil, // 207: openshell.v1.StoredPolicyRevision.ProvenanceEntry - nil, // 208: openshell.v1.CreateWorkspaceRequest.LabelsEntry - (*datamodelv1.ObjectMeta)(nil), // 209: openshell.datamodel.v1.ObjectMeta - (*sandboxv1.SandboxPolicy)(nil), // 210: openshell.sandbox.v1.SandboxPolicy - (*structpb.Struct)(nil), // 211: google.protobuf.Struct - (*datamodelv1.Provider)(nil), // 212: openshell.datamodel.v1.Provider - (*sandboxv1.NetworkEndpoint)(nil), // 213: openshell.sandbox.v1.NetworkEndpoint - (*sandboxv1.NetworkBinary)(nil), // 214: openshell.sandbox.v1.NetworkBinary - (*sandboxv1.SettingValue)(nil), // 215: openshell.sandbox.v1.SettingValue - (*sandboxv1.NetworkPolicyRule)(nil), // 216: openshell.sandbox.v1.NetworkPolicyRule - (*sandboxv1.L7DenyRule)(nil), // 217: openshell.sandbox.v1.L7DenyRule - (*sandboxv1.L7Rule)(nil), // 218: openshell.sandbox.v1.L7Rule - (*datamodelv1.Workspace)(nil), // 219: openshell.datamodel.v1.Workspace - (*sandboxv1.GetSandboxConfigRequest)(nil), // 220: openshell.sandbox.v1.GetSandboxConfigRequest - (*sandboxv1.GetGatewayConfigRequest)(nil), // 221: openshell.sandbox.v1.GetGatewayConfigRequest - (*sandboxv1.GetSandboxConfigResponse)(nil), // 222: openshell.sandbox.v1.GetSandboxConfigResponse - (*sandboxv1.GetGatewayConfigResponse)(nil), // 223: openshell.sandbox.v1.GetGatewayConfigResponse + (*SuspendSandboxRequest)(nil), // 33: openshell.v1.SuspendSandboxRequest + (*ResumeSandboxRequest)(nil), // 34: openshell.v1.ResumeSandboxRequest + (*SandboxResponse)(nil), // 35: openshell.v1.SandboxResponse + (*ListSandboxesResponse)(nil), // 36: openshell.v1.ListSandboxesResponse + (*ListSandboxProvidersResponse)(nil), // 37: openshell.v1.ListSandboxProvidersResponse + (*AttachSandboxProviderResponse)(nil), // 38: openshell.v1.AttachSandboxProviderResponse + (*DetachSandboxProviderResponse)(nil), // 39: openshell.v1.DetachSandboxProviderResponse + (*DeleteSandboxResponse)(nil), // 40: openshell.v1.DeleteSandboxResponse + (*CreateSshSessionRequest)(nil), // 41: openshell.v1.CreateSshSessionRequest + (*CreateSshSessionResponse)(nil), // 42: openshell.v1.CreateSshSessionResponse + (*ExposeServiceRequest)(nil), // 43: openshell.v1.ExposeServiceRequest + (*GetServiceRequest)(nil), // 44: openshell.v1.GetServiceRequest + (*ListServicesRequest)(nil), // 45: openshell.v1.ListServicesRequest + (*ListServicesResponse)(nil), // 46: openshell.v1.ListServicesResponse + (*DeleteServiceRequest)(nil), // 47: openshell.v1.DeleteServiceRequest + (*DeleteServiceResponse)(nil), // 48: openshell.v1.DeleteServiceResponse + (*ServiceEndpoint)(nil), // 49: openshell.v1.ServiceEndpoint + (*ServiceEndpointResponse)(nil), // 50: openshell.v1.ServiceEndpointResponse + (*RevokeSshSessionRequest)(nil), // 51: openshell.v1.RevokeSshSessionRequest + (*RevokeSshSessionResponse)(nil), // 52: openshell.v1.RevokeSshSessionResponse + (*ExecSandboxRequest)(nil), // 53: openshell.v1.ExecSandboxRequest + (*ExecSandboxStdout)(nil), // 54: openshell.v1.ExecSandboxStdout + (*ExecSandboxStderr)(nil), // 55: openshell.v1.ExecSandboxStderr + (*ExecSandboxExit)(nil), // 56: openshell.v1.ExecSandboxExit + (*ExecSandboxEvent)(nil), // 57: openshell.v1.ExecSandboxEvent + (*TcpForwardInit)(nil), // 58: openshell.v1.TcpForwardInit + (*TcpForwardFrame)(nil), // 59: openshell.v1.TcpForwardFrame + (*ExecSandboxInput)(nil), // 60: openshell.v1.ExecSandboxInput + (*ExecSandboxWindowResize)(nil), // 61: openshell.v1.ExecSandboxWindowResize + (*SshSession)(nil), // 62: openshell.v1.SshSession + (*WatchSandboxRequest)(nil), // 63: openshell.v1.WatchSandboxRequest + (*SandboxStreamEvent)(nil), // 64: openshell.v1.SandboxStreamEvent + (*SandboxLogLine)(nil), // 65: openshell.v1.SandboxLogLine + (*SandboxStreamWarning)(nil), // 66: openshell.v1.SandboxStreamWarning + (*CreateProviderRequest)(nil), // 67: openshell.v1.CreateProviderRequest + (*GetProviderRequest)(nil), // 68: openshell.v1.GetProviderRequest + (*ListProvidersRequest)(nil), // 69: openshell.v1.ListProvidersRequest + (*UpdateProviderRequest)(nil), // 70: openshell.v1.UpdateProviderRequest + (*DeleteProviderRequest)(nil), // 71: openshell.v1.DeleteProviderRequest + (*ProviderResponse)(nil), // 72: openshell.v1.ProviderResponse + (*ListProvidersResponse)(nil), // 73: openshell.v1.ListProvidersResponse + (*ListProviderProfilesRequest)(nil), // 74: openshell.v1.ListProviderProfilesRequest + (*GetProviderProfileRequest)(nil), // 75: openshell.v1.GetProviderProfileRequest + (*ProviderProfileImportItem)(nil), // 76: openshell.v1.ProviderProfileImportItem + (*ProviderProfileDiagnostic)(nil), // 77: openshell.v1.ProviderProfileDiagnostic + (*ProviderCredentialTokenGrantAudienceOverride)(nil), // 78: openshell.v1.ProviderCredentialTokenGrantAudienceOverride + (*ProviderCredentialTokenGrant)(nil), // 79: openshell.v1.ProviderCredentialTokenGrant + (*ProviderProfileCredential)(nil), // 80: openshell.v1.ProviderProfileCredential + (*ProviderCredentialRefreshMaterial)(nil), // 81: openshell.v1.ProviderCredentialRefreshMaterial + (*ProviderCredentialRefreshOutput)(nil), // 82: openshell.v1.ProviderCredentialRefreshOutput + (*ProviderCredentialRefresh)(nil), // 83: openshell.v1.ProviderCredentialRefresh + (*ProviderCredentialRefreshStatus)(nil), // 84: openshell.v1.ProviderCredentialRefreshStatus + (*ProviderProfileDiscovery)(nil), // 85: openshell.v1.ProviderProfileDiscovery + (*StoredProviderCredentialRefreshState)(nil), // 86: openshell.v1.StoredProviderCredentialRefreshState + (*GetProviderRefreshStatusRequest)(nil), // 87: openshell.v1.GetProviderRefreshStatusRequest + (*GetProviderRefreshStatusResponse)(nil), // 88: openshell.v1.GetProviderRefreshStatusResponse + (*ConfigureProviderRefreshRequest)(nil), // 89: openshell.v1.ConfigureProviderRefreshRequest + (*ConfigureProviderRefreshResponse)(nil), // 90: openshell.v1.ConfigureProviderRefreshResponse + (*RotateProviderCredentialRequest)(nil), // 91: openshell.v1.RotateProviderCredentialRequest + (*RotateProviderCredentialResponse)(nil), // 92: openshell.v1.RotateProviderCredentialResponse + (*DeleteProviderRefreshRequest)(nil), // 93: openshell.v1.DeleteProviderRefreshRequest + (*DeleteProviderRefreshResponse)(nil), // 94: openshell.v1.DeleteProviderRefreshResponse + (*ProviderProfile)(nil), // 95: openshell.v1.ProviderProfile + (*StoredProviderProfile)(nil), // 96: openshell.v1.StoredProviderProfile + (*ProviderProfileResponse)(nil), // 97: openshell.v1.ProviderProfileResponse + (*ListProviderProfilesResponse)(nil), // 98: openshell.v1.ListProviderProfilesResponse + (*ImportProviderProfilesRequest)(nil), // 99: openshell.v1.ImportProviderProfilesRequest + (*ImportProviderProfilesResponse)(nil), // 100: openshell.v1.ImportProviderProfilesResponse + (*UpdateProviderProfilesRequest)(nil), // 101: openshell.v1.UpdateProviderProfilesRequest + (*UpdateProviderProfilesResponse)(nil), // 102: openshell.v1.UpdateProviderProfilesResponse + (*LintProviderProfilesRequest)(nil), // 103: openshell.v1.LintProviderProfilesRequest + (*LintProviderProfilesResponse)(nil), // 104: openshell.v1.LintProviderProfilesResponse + (*DeleteProviderResponse)(nil), // 105: openshell.v1.DeleteProviderResponse + (*DeleteProviderProfileRequest)(nil), // 106: openshell.v1.DeleteProviderProfileRequest + (*DeleteProviderProfileResponse)(nil), // 107: openshell.v1.DeleteProviderProfileResponse + (*GetSandboxProviderEnvironmentRequest)(nil), // 108: openshell.v1.GetSandboxProviderEnvironmentRequest + (*GetSandboxProviderEnvironmentResponse)(nil), // 109: openshell.v1.GetSandboxProviderEnvironmentResponse + (*UpdateConfigRequest)(nil), // 110: openshell.v1.UpdateConfigRequest + (*PolicyMergeOperation)(nil), // 111: openshell.v1.PolicyMergeOperation + (*AddNetworkRule)(nil), // 112: openshell.v1.AddNetworkRule + (*RemoveNetworkEndpoint)(nil), // 113: openshell.v1.RemoveNetworkEndpoint + (*RemoveNetworkRule)(nil), // 114: openshell.v1.RemoveNetworkRule + (*AddDenyRules)(nil), // 115: openshell.v1.AddDenyRules + (*AddAllowRules)(nil), // 116: openshell.v1.AddAllowRules + (*RemoveNetworkBinary)(nil), // 117: openshell.v1.RemoveNetworkBinary + (*UpdateConfigResponse)(nil), // 118: openshell.v1.UpdateConfigResponse + (*GetSandboxPolicyStatusRequest)(nil), // 119: openshell.v1.GetSandboxPolicyStatusRequest + (*GetSandboxPolicyStatusResponse)(nil), // 120: openshell.v1.GetSandboxPolicyStatusResponse + (*ListSandboxPoliciesRequest)(nil), // 121: openshell.v1.ListSandboxPoliciesRequest + (*ListSandboxPoliciesResponse)(nil), // 122: openshell.v1.ListSandboxPoliciesResponse + (*ReportPolicyStatusRequest)(nil), // 123: openshell.v1.ReportPolicyStatusRequest + (*ReportPolicyStatusResponse)(nil), // 124: openshell.v1.ReportPolicyStatusResponse + (*SandboxPolicyRevision)(nil), // 125: openshell.v1.SandboxPolicyRevision + (*GetSandboxLogsRequest)(nil), // 126: openshell.v1.GetSandboxLogsRequest + (*PushSandboxLogsRequest)(nil), // 127: openshell.v1.PushSandboxLogsRequest + (*PushSandboxLogsResponse)(nil), // 128: openshell.v1.PushSandboxLogsResponse + (*GetSandboxLogsResponse)(nil), // 129: openshell.v1.GetSandboxLogsResponse + (*SupervisorMessage)(nil), // 130: openshell.v1.SupervisorMessage + (*GatewayMessage)(nil), // 131: openshell.v1.GatewayMessage + (*SupervisorHello)(nil), // 132: openshell.v1.SupervisorHello + (*SessionAccepted)(nil), // 133: openshell.v1.SessionAccepted + (*SessionRejected)(nil), // 134: openshell.v1.SessionRejected + (*SupervisorHeartbeat)(nil), // 135: openshell.v1.SupervisorHeartbeat + (*GatewayHeartbeat)(nil), // 136: openshell.v1.GatewayHeartbeat + (*RelayOpen)(nil), // 137: openshell.v1.RelayOpen + (*SshRelayTarget)(nil), // 138: openshell.v1.SshRelayTarget + (*TcpRelayTarget)(nil), // 139: openshell.v1.TcpRelayTarget + (*RelayInit)(nil), // 140: openshell.v1.RelayInit + (*RelayFrame)(nil), // 141: openshell.v1.RelayFrame + (*RelayOpenResult)(nil), // 142: openshell.v1.RelayOpenResult + (*RelayClose)(nil), // 143: openshell.v1.RelayClose + (*L7RequestSample)(nil), // 144: openshell.v1.L7RequestSample + (*DenialSummary)(nil), // 145: openshell.v1.DenialSummary + (*DenialGroupCount)(nil), // 146: openshell.v1.DenialGroupCount + (*NetworkActivitySummary)(nil), // 147: openshell.v1.NetworkActivitySummary + (*PolicyChunk)(nil), // 148: openshell.v1.PolicyChunk + (*DraftPolicyUpdate)(nil), // 149: openshell.v1.DraftPolicyUpdate + (*SubmitPolicyAnalysisRequest)(nil), // 150: openshell.v1.SubmitPolicyAnalysisRequest + (*SubmitPolicyAnalysisResponse)(nil), // 151: openshell.v1.SubmitPolicyAnalysisResponse + (*GetDraftPolicyRequest)(nil), // 152: openshell.v1.GetDraftPolicyRequest + (*GetDraftPolicyResponse)(nil), // 153: openshell.v1.GetDraftPolicyResponse + (*ApproveDraftChunkRequest)(nil), // 154: openshell.v1.ApproveDraftChunkRequest + (*ApproveDraftChunkResponse)(nil), // 155: openshell.v1.ApproveDraftChunkResponse + (*RejectDraftChunkRequest)(nil), // 156: openshell.v1.RejectDraftChunkRequest + (*RejectDraftChunkResponse)(nil), // 157: openshell.v1.RejectDraftChunkResponse + (*ApproveAllDraftChunksRequest)(nil), // 158: openshell.v1.ApproveAllDraftChunksRequest + (*ApproveAllDraftChunksResponse)(nil), // 159: openshell.v1.ApproveAllDraftChunksResponse + (*EditDraftChunkRequest)(nil), // 160: openshell.v1.EditDraftChunkRequest + (*EditDraftChunkResponse)(nil), // 161: openshell.v1.EditDraftChunkResponse + (*UndoDraftChunkRequest)(nil), // 162: openshell.v1.UndoDraftChunkRequest + (*UndoDraftChunkResponse)(nil), // 163: openshell.v1.UndoDraftChunkResponse + (*ClearDraftChunksRequest)(nil), // 164: openshell.v1.ClearDraftChunksRequest + (*ClearDraftChunksResponse)(nil), // 165: openshell.v1.ClearDraftChunksResponse + (*GetDraftHistoryRequest)(nil), // 166: openshell.v1.GetDraftHistoryRequest + (*DraftHistoryEntry)(nil), // 167: openshell.v1.DraftHistoryEntry + (*GetDraftHistoryResponse)(nil), // 168: openshell.v1.GetDraftHistoryResponse + (*PolicyRevisionPayload)(nil), // 169: openshell.v1.PolicyRevisionPayload + (*DraftChunkPayload)(nil), // 170: openshell.v1.DraftChunkPayload + (*StoredPolicyRevision)(nil), // 171: openshell.v1.StoredPolicyRevision + (*StoredDraftChunk)(nil), // 172: openshell.v1.StoredDraftChunk + (*CreateWorkspaceRequest)(nil), // 173: openshell.v1.CreateWorkspaceRequest + (*CreateWorkspaceResponse)(nil), // 174: openshell.v1.CreateWorkspaceResponse + (*GetWorkspaceRequest)(nil), // 175: openshell.v1.GetWorkspaceRequest + (*GetWorkspaceResponse)(nil), // 176: openshell.v1.GetWorkspaceResponse + (*ListWorkspacesRequest)(nil), // 177: openshell.v1.ListWorkspacesRequest + (*ListWorkspacesResponse)(nil), // 178: openshell.v1.ListWorkspacesResponse + (*DeleteWorkspaceRequest)(nil), // 179: openshell.v1.DeleteWorkspaceRequest + (*DeleteWorkspaceResponse)(nil), // 180: openshell.v1.DeleteWorkspaceResponse + (*WorkspaceMember)(nil), // 181: openshell.v1.WorkspaceMember + (*AddWorkspaceMemberRequest)(nil), // 182: openshell.v1.AddWorkspaceMemberRequest + (*AddWorkspaceMemberResponse)(nil), // 183: openshell.v1.AddWorkspaceMemberResponse + (*RemoveWorkspaceMemberRequest)(nil), // 184: openshell.v1.RemoveWorkspaceMemberRequest + (*RemoveWorkspaceMemberResponse)(nil), // 185: openshell.v1.RemoveWorkspaceMemberResponse + (*ListWorkspaceMembersRequest)(nil), // 186: openshell.v1.ListWorkspaceMembersRequest + (*ListWorkspaceMembersResponse)(nil), // 187: openshell.v1.ListWorkspaceMembersResponse + nil, // 188: openshell.v1.SandboxSpec.EnvironmentEntry + nil, // 189: openshell.v1.SandboxTemplate.LabelsEntry + nil, // 190: openshell.v1.SandboxTemplate.AnnotationsEntry + nil, // 191: openshell.v1.SandboxTemplate.EnvironmentEntry + nil, // 192: openshell.v1.PlatformEvent.MetadataEntry + nil, // 193: openshell.v1.CreateSandboxRequest.LabelsEntry + nil, // 194: openshell.v1.CreateSandboxRequest.AnnotationsEntry + nil, // 195: openshell.v1.ExecSandboxRequest.EnvironmentEntry + nil, // 196: openshell.v1.SandboxLogLine.FieldsEntry + nil, // 197: openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry + nil, // 198: openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry + nil, // 199: openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry + nil, // 200: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + nil, // 201: openshell.v1.ProviderProfile.AnnotationsEntry + nil, // 202: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + nil, // 203: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry + nil, // 204: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + nil, // 205: openshell.v1.UpdateConfigRequest.AnnotationsEntry + nil, // 206: openshell.v1.UpdateConfigResponse.AnnotationsEntry + nil, // 207: openshell.v1.SandboxPolicyRevision.ProvenanceEntry + nil, // 208: openshell.v1.PolicyRevisionPayload.ProvenanceEntry + nil, // 209: openshell.v1.StoredPolicyRevision.ProvenanceEntry + nil, // 210: openshell.v1.CreateWorkspaceRequest.LabelsEntry + (*datamodelv1.ObjectMeta)(nil), // 211: openshell.datamodel.v1.ObjectMeta + (*sandboxv1.SandboxPolicy)(nil), // 212: openshell.sandbox.v1.SandboxPolicy + (*structpb.Struct)(nil), // 213: google.protobuf.Struct + (*datamodelv1.Provider)(nil), // 214: openshell.datamodel.v1.Provider + (*sandboxv1.NetworkEndpoint)(nil), // 215: openshell.sandbox.v1.NetworkEndpoint + (*sandboxv1.NetworkBinary)(nil), // 216: openshell.sandbox.v1.NetworkBinary + (*sandboxv1.SettingValue)(nil), // 217: openshell.sandbox.v1.SettingValue + (*sandboxv1.NetworkPolicyRule)(nil), // 218: openshell.sandbox.v1.NetworkPolicyRule + (*sandboxv1.L7DenyRule)(nil), // 219: openshell.sandbox.v1.L7DenyRule + (*sandboxv1.L7Rule)(nil), // 220: openshell.sandbox.v1.L7Rule + (*datamodelv1.Workspace)(nil), // 221: openshell.datamodel.v1.Workspace + (*sandboxv1.GetSandboxConfigRequest)(nil), // 222: openshell.sandbox.v1.GetSandboxConfigRequest + (*sandboxv1.GetGatewayConfigRequest)(nil), // 223: openshell.sandbox.v1.GetGatewayConfigRequest + (*sandboxv1.GetSandboxConfigResponse)(nil), // 224: openshell.sandbox.v1.GetSandboxConfigResponse + (*sandboxv1.GetGatewayConfigResponse)(nil), // 225: openshell.sandbox.v1.GetGatewayConfigResponse } var file_openshell_proto_depIdxs = []int32{ 4, // 0: openshell.v1.HealthResponse.status:type_name -> openshell.v1.ServiceStatus 4, // 1: openshell.v1.GetGatewayInfoResponse.status:type_name -> openshell.v1.ServiceStatus 16, // 2: openshell.v1.GetGatewayInfoResponse.compute_drivers:type_name -> openshell.v1.ComputeDriverInfo 17, // 3: openshell.v1.ComputeDriverInfo.capabilities:type_name -> openshell.v1.ComputeDriverCapabilities - 209, // 4: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 211, // 4: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 19, // 5: openshell.v1.Sandbox.spec:type_name -> openshell.v1.SandboxSpec 23, // 6: openshell.v1.Sandbox.status:type_name -> openshell.v1.SandboxStatus - 186, // 7: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry + 188, // 7: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry 22, // 8: openshell.v1.SandboxSpec.template:type_name -> openshell.v1.SandboxTemplate - 210, // 9: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 212, // 9: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy 20, // 10: openshell.v1.SandboxSpec.resource_requirements:type_name -> openshell.v1.ResourceRequirements 21, // 11: openshell.v1.ResourceRequirements.gpu:type_name -> openshell.v1.GpuResourceRequirements - 187, // 12: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry - 188, // 13: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry - 189, // 14: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry - 211, // 15: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct - 211, // 16: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct + 189, // 12: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry + 190, // 13: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry + 191, // 14: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry + 213, // 15: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct + 213, // 16: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct 24, // 17: openshell.v1.SandboxStatus.conditions:type_name -> openshell.v1.SandboxCondition 0, // 18: openshell.v1.SandboxStatus.phase:type_name -> openshell.v1.SandboxPhase - 190, // 19: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry + 192, // 19: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry 19, // 20: openshell.v1.CreateSandboxRequest.spec:type_name -> openshell.v1.SandboxSpec - 191, // 21: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry - 192, // 22: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry + 193, // 21: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry + 194, // 22: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry 18, // 23: openshell.v1.SandboxResponse.sandbox:type_name -> openshell.v1.Sandbox 18, // 24: openshell.v1.ListSandboxesResponse.sandboxes:type_name -> openshell.v1.Sandbox - 212, // 25: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 214, // 25: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider 18, // 26: openshell.v1.AttachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox 18, // 27: openshell.v1.DetachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox - 48, // 28: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse - 209, // 29: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 47, // 30: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint - 193, // 31: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry - 52, // 32: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout - 53, // 33: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr - 54, // 34: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit - 136, // 35: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget - 137, // 36: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget - 56, // 37: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit - 51, // 38: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest - 59, // 39: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize - 209, // 40: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 50, // 28: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse + 211, // 29: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 49, // 30: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint + 195, // 31: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry + 54, // 32: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout + 55, // 33: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr + 56, // 34: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit + 138, // 35: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget + 139, // 36: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget + 58, // 37: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit + 53, // 38: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest + 61, // 39: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize + 211, // 40: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 18, // 41: openshell.v1.SandboxStreamEvent.sandbox:type_name -> openshell.v1.Sandbox - 63, // 42: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine + 65, // 42: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine 25, // 43: openshell.v1.SandboxStreamEvent.event:type_name -> openshell.v1.PlatformEvent - 64, // 44: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning - 147, // 45: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate - 194, // 46: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry - 212, // 47: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 212, // 48: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 195, // 49: openshell.v1.UpdateProviderRequest.credential_expires_at_ms:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry - 212, // 50: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider - 212, // 51: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider - 93, // 52: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile - 76, // 53: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride - 81, // 54: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh - 77, // 55: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant + 66, // 44: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning + 149, // 45: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate + 196, // 46: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry + 214, // 47: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 214, // 48: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 197, // 49: openshell.v1.UpdateProviderRequest.credential_expires_at_ms:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry + 214, // 50: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider + 214, // 51: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 95, // 52: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile + 78, // 53: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride + 83, // 54: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh + 79, // 55: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant 1, // 56: openshell.v1.ProviderCredentialRefresh.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 79, // 57: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial - 80, // 58: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput + 81, // 57: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial + 82, // 58: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput 1, // 59: openshell.v1.ProviderCredentialRefreshStatus.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 209, // 60: openshell.v1.StoredProviderCredentialRefreshState.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 211, // 60: openshell.v1.StoredProviderCredentialRefreshState.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 1, // 61: openshell.v1.StoredProviderCredentialRefreshState.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 196, // 62: openshell.v1.StoredProviderCredentialRefreshState.material:type_name -> openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry - 197, // 63: openshell.v1.StoredProviderCredentialRefreshState.additional_output_keys:type_name -> openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - 82, // 64: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 198, // 62: openshell.v1.StoredProviderCredentialRefreshState.material:type_name -> openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry + 199, // 63: openshell.v1.StoredProviderCredentialRefreshState.additional_output_keys:type_name -> openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry + 84, // 64: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus 1, // 65: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 198, // 66: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - 82, // 67: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 82, // 68: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 200, // 66: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + 84, // 67: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 84, // 68: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus 2, // 69: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory - 78, // 70: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential - 213, // 71: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint - 214, // 72: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 83, // 73: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery - 199, // 74: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry - 209, // 75: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 93, // 76: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile - 93, // 77: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile - 93, // 78: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 74, // 79: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 75, // 80: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 93, // 81: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 74, // 82: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem - 75, // 83: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 93, // 84: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile - 74, // 85: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 75, // 86: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 200, // 87: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - 201, // 88: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry - 202, // 89: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - 210, // 90: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 215, // 91: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue - 109, // 92: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation - 203, // 93: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry - 110, // 94: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule - 111, // 95: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint - 112, // 96: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule - 113, // 97: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules - 114, // 98: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules - 115, // 99: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary - 216, // 100: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 217, // 101: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule - 218, // 102: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule - 204, // 103: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry - 123, // 104: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision - 123, // 105: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision + 80, // 70: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential + 215, // 71: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint + 216, // 72: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 85, // 73: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery + 201, // 74: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry + 211, // 75: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 95, // 76: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile + 95, // 77: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile + 95, // 78: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 76, // 79: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 80: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 95, // 81: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 76, // 82: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 83: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 95, // 84: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile + 76, // 85: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 86: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 202, // 87: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + 203, // 88: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry + 204, // 89: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + 212, // 90: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 217, // 91: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue + 111, // 92: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation + 205, // 93: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry + 112, // 94: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule + 113, // 95: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint + 114, // 96: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule + 115, // 97: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules + 116, // 98: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules + 117, // 99: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary + 218, // 100: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 219, // 101: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule + 220, // 102: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule + 206, // 103: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry + 125, // 104: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision + 125, // 105: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision 3, // 106: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus 3, // 107: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus - 210, // 108: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 205, // 109: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry - 63, // 110: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine - 63, // 111: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine - 130, // 112: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello - 133, // 113: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat - 140, // 114: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult - 141, // 115: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose - 131, // 116: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted - 132, // 117: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected - 134, // 118: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat - 135, // 119: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen - 141, // 120: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose - 136, // 121: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget - 137, // 122: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget - 138, // 123: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit - 142, // 124: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample - 144, // 125: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount - 216, // 126: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 143, // 127: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary - 146, // 128: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk - 145, // 129: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary - 146, // 130: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk - 216, // 131: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 165, // 132: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry - 210, // 133: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 206, // 134: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry - 216, // 135: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 207, // 136: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry - 208, // 137: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry - 219, // 138: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 219, // 139: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 219, // 140: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace - 209, // 141: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 212, // 108: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 207, // 109: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry + 65, // 110: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine + 65, // 111: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine + 132, // 112: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello + 135, // 113: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat + 142, // 114: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult + 143, // 115: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose + 133, // 116: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted + 134, // 117: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected + 136, // 118: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat + 137, // 119: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen + 143, // 120: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose + 138, // 121: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget + 139, // 122: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget + 140, // 123: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit + 144, // 124: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample + 146, // 125: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount + 218, // 126: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 145, // 127: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary + 148, // 128: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk + 147, // 129: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary + 148, // 130: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk + 218, // 131: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 167, // 132: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry + 212, // 133: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 208, // 134: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry + 218, // 135: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 209, // 136: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry + 210, // 137: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry + 221, // 138: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 221, // 139: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 221, // 140: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace + 211, // 141: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 5, // 142: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole 5, // 143: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole - 179, // 144: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember - 179, // 145: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember - 78, // 146: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential + 181, // 144: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember + 181, // 145: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember + 80, // 146: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential 10, // 147: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest 12, // 148: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest 14, // 149: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest @@ -14254,126 +14388,130 @@ var file_openshell_proto_depIdxs = []int32{ 30, // 154: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest 31, // 155: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest 32, // 156: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest - 39, // 157: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest - 41, // 158: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest - 42, // 159: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest - 43, // 160: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest - 45, // 161: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest - 49, // 162: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest - 51, // 163: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest - 57, // 164: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame - 58, // 165: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput - 65, // 166: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest - 66, // 167: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest - 67, // 168: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest - 72, // 169: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest - 73, // 170: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest - 97, // 171: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest - 99, // 172: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest - 101, // 173: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest - 68, // 174: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest - 85, // 175: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest - 87, // 176: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest - 89, // 177: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest - 91, // 178: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest - 69, // 179: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest - 104, // 180: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest - 220, // 181: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest - 221, // 182: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest - 108, // 183: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest - 117, // 184: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest - 119, // 185: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest - 121, // 186: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest - 106, // 187: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest - 124, // 188: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest - 125, // 189: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest - 128, // 190: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage - 139, // 191: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame - 61, // 192: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest - 148, // 193: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest - 150, // 194: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest - 152, // 195: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest - 154, // 196: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest - 156, // 197: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest - 158, // 198: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest - 160, // 199: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest - 162, // 200: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest - 164, // 201: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest - 6, // 202: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest - 8, // 203: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest - 171, // 204: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest - 173, // 205: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest - 175, // 206: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest - 177, // 207: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest - 180, // 208: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest - 182, // 209: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest - 184, // 210: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest - 11, // 211: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse - 13, // 212: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse - 15, // 213: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse - 33, // 214: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse - 33, // 215: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse - 34, // 216: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse - 35, // 217: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse - 36, // 218: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse - 37, // 219: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse - 38, // 220: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse - 40, // 221: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse - 48, // 222: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse - 48, // 223: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse - 44, // 224: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse - 46, // 225: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse - 50, // 226: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse - 55, // 227: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent - 57, // 228: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame - 55, // 229: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent - 70, // 230: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse - 70, // 231: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse - 71, // 232: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse - 96, // 233: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse - 95, // 234: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse - 98, // 235: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse - 100, // 236: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse - 102, // 237: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse - 70, // 238: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse - 86, // 239: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse - 88, // 240: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse - 90, // 241: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse - 92, // 242: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse - 103, // 243: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse - 105, // 244: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse - 222, // 245: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse - 223, // 246: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse - 116, // 247: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse - 118, // 248: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse - 120, // 249: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse - 122, // 250: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse - 107, // 251: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse - 127, // 252: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse - 126, // 253: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse - 129, // 254: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage - 139, // 255: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame - 62, // 256: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent - 149, // 257: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse - 151, // 258: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse - 153, // 259: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse - 155, // 260: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse - 157, // 261: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse - 159, // 262: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse - 161, // 263: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse - 163, // 264: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse - 166, // 265: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse - 7, // 266: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse - 9, // 267: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse - 172, // 268: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse - 174, // 269: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse - 176, // 270: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse - 178, // 271: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse - 181, // 272: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse - 183, // 273: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse - 185, // 274: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse - 211, // [211:275] is the sub-list for method output_type - 147, // [147:211] is the sub-list for method input_type + 33, // 157: openshell.v1.OpenShell.SuspendSandbox:input_type -> openshell.v1.SuspendSandboxRequest + 34, // 158: openshell.v1.OpenShell.ResumeSandbox:input_type -> openshell.v1.ResumeSandboxRequest + 41, // 159: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest + 43, // 160: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest + 44, // 161: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest + 45, // 162: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest + 47, // 163: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest + 51, // 164: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest + 53, // 165: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest + 59, // 166: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame + 60, // 167: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput + 67, // 168: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest + 68, // 169: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest + 69, // 170: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest + 74, // 171: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest + 75, // 172: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest + 99, // 173: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest + 101, // 174: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest + 103, // 175: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest + 70, // 176: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest + 87, // 177: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest + 89, // 178: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest + 91, // 179: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest + 93, // 180: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest + 71, // 181: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest + 106, // 182: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest + 222, // 183: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest + 223, // 184: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest + 110, // 185: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest + 119, // 186: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest + 121, // 187: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest + 123, // 188: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest + 108, // 189: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest + 126, // 190: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest + 127, // 191: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest + 130, // 192: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage + 141, // 193: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame + 63, // 194: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest + 150, // 195: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest + 152, // 196: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest + 154, // 197: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest + 156, // 198: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest + 158, // 199: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest + 160, // 200: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest + 162, // 201: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest + 164, // 202: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest + 166, // 203: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest + 6, // 204: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest + 8, // 205: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest + 173, // 206: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest + 175, // 207: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest + 177, // 208: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest + 179, // 209: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest + 182, // 210: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest + 184, // 211: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest + 186, // 212: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest + 11, // 213: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse + 13, // 214: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse + 15, // 215: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse + 35, // 216: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse + 35, // 217: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse + 36, // 218: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse + 37, // 219: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse + 38, // 220: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse + 39, // 221: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse + 40, // 222: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse + 35, // 223: openshell.v1.OpenShell.SuspendSandbox:output_type -> openshell.v1.SandboxResponse + 35, // 224: openshell.v1.OpenShell.ResumeSandbox:output_type -> openshell.v1.SandboxResponse + 42, // 225: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse + 50, // 226: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse + 50, // 227: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse + 46, // 228: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse + 48, // 229: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse + 52, // 230: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse + 57, // 231: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent + 59, // 232: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame + 57, // 233: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent + 72, // 234: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse + 72, // 235: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse + 73, // 236: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse + 98, // 237: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse + 97, // 238: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse + 100, // 239: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse + 102, // 240: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse + 104, // 241: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse + 72, // 242: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse + 88, // 243: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse + 90, // 244: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse + 92, // 245: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse + 94, // 246: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse + 105, // 247: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse + 107, // 248: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse + 224, // 249: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse + 225, // 250: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse + 118, // 251: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse + 120, // 252: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse + 122, // 253: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse + 124, // 254: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse + 109, // 255: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse + 129, // 256: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse + 128, // 257: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse + 131, // 258: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage + 141, // 259: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame + 64, // 260: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent + 151, // 261: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse + 153, // 262: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse + 155, // 263: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse + 157, // 264: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse + 159, // 265: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse + 161, // 266: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse + 163, // 267: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse + 165, // 268: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse + 168, // 269: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse + 7, // 270: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse + 9, // 271: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse + 174, // 272: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse + 176, // 273: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse + 178, // 274: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse + 180, // 275: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse + 183, // 276: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse + 185, // 277: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse + 187, // 278: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse + 213, // [213:279] is the sub-list for method output_type + 147, // [147:213] is the sub-list for method input_type 147, // [147:147] is the sub-list for extension type_name 147, // [147:147] is the sub-list for extension extendee 0, // [0:147] is the sub-list for field type_name @@ -14386,33 +14524,33 @@ func file_openshell_proto_init() { } file_openshell_proto_msgTypes[15].OneofWrappers = []any{} file_openshell_proto_msgTypes[16].OneofWrappers = []any{} - file_openshell_proto_msgTypes[49].OneofWrappers = []any{ + file_openshell_proto_msgTypes[51].OneofWrappers = []any{ (*ExecSandboxEvent_Stdout)(nil), (*ExecSandboxEvent_Stderr)(nil), (*ExecSandboxEvent_Exit)(nil), } - file_openshell_proto_msgTypes[50].OneofWrappers = []any{ + file_openshell_proto_msgTypes[52].OneofWrappers = []any{ (*TcpForwardInit_Ssh)(nil), (*TcpForwardInit_Tcp)(nil), } - file_openshell_proto_msgTypes[51].OneofWrappers = []any{ + file_openshell_proto_msgTypes[53].OneofWrappers = []any{ (*TcpForwardFrame_Init)(nil), (*TcpForwardFrame_Data)(nil), } - file_openshell_proto_msgTypes[52].OneofWrappers = []any{ + file_openshell_proto_msgTypes[54].OneofWrappers = []any{ (*ExecSandboxInput_Start)(nil), (*ExecSandboxInput_Stdin)(nil), (*ExecSandboxInput_Resize)(nil), } - file_openshell_proto_msgTypes[56].OneofWrappers = []any{ + file_openshell_proto_msgTypes[58].OneofWrappers = []any{ (*SandboxStreamEvent_Sandbox)(nil), (*SandboxStreamEvent_Log)(nil), (*SandboxStreamEvent_Event)(nil), (*SandboxStreamEvent_Warning)(nil), (*SandboxStreamEvent_DraftPolicyUpdate)(nil), } - file_openshell_proto_msgTypes[81].OneofWrappers = []any{} - file_openshell_proto_msgTypes[103].OneofWrappers = []any{ + file_openshell_proto_msgTypes[83].OneofWrappers = []any{} + file_openshell_proto_msgTypes[105].OneofWrappers = []any{ (*PolicyMergeOperation_AddRule)(nil), (*PolicyMergeOperation_RemoveEndpoint)(nil), (*PolicyMergeOperation_RemoveRule)(nil), @@ -14420,36 +14558,36 @@ func file_openshell_proto_init() { (*PolicyMergeOperation_AddAllowRules)(nil), (*PolicyMergeOperation_RemoveBinary)(nil), } - file_openshell_proto_msgTypes[122].OneofWrappers = []any{ + file_openshell_proto_msgTypes[124].OneofWrappers = []any{ (*SupervisorMessage_Hello)(nil), (*SupervisorMessage_Heartbeat)(nil), (*SupervisorMessage_RelayOpenResult)(nil), (*SupervisorMessage_RelayClose)(nil), } - file_openshell_proto_msgTypes[123].OneofWrappers = []any{ + file_openshell_proto_msgTypes[125].OneofWrappers = []any{ (*GatewayMessage_SessionAccepted)(nil), (*GatewayMessage_SessionRejected)(nil), (*GatewayMessage_Heartbeat)(nil), (*GatewayMessage_RelayOpen)(nil), (*GatewayMessage_RelayClose)(nil), } - file_openshell_proto_msgTypes[129].OneofWrappers = []any{ + file_openshell_proto_msgTypes[131].OneofWrappers = []any{ (*RelayOpen_Ssh)(nil), (*RelayOpen_Tcp)(nil), } - file_openshell_proto_msgTypes[133].OneofWrappers = []any{ + file_openshell_proto_msgTypes[135].OneofWrappers = []any{ (*RelayFrame_Init)(nil), (*RelayFrame_Data)(nil), } - file_openshell_proto_msgTypes[163].OneofWrappers = []any{} - file_openshell_proto_msgTypes[164].OneofWrappers = []any{} + file_openshell_proto_msgTypes[165].OneofWrappers = []any{} + file_openshell_proto_msgTypes[166].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_openshell_proto_rawDesc), len(file_openshell_proto_rawDesc)), NumEnums: 6, - NumMessages: 203, + NumMessages: 205, NumExtensions: 0, NumServices: 1, }, diff --git a/sdk/go/proto/openshellv1/openshell_grpc.pb.go b/sdk/go/proto/openshellv1/openshell_grpc.pb.go index 40d625a394..ef4b4c2669 100644 --- a/sdk/go/proto/openshellv1/openshell_grpc.pb.go +++ b/sdk/go/proto/openshellv1/openshell_grpc.pb.go @@ -33,6 +33,8 @@ const ( OpenShell_AttachSandboxProvider_FullMethodName = "/openshell.v1.OpenShell/AttachSandboxProvider" OpenShell_DetachSandboxProvider_FullMethodName = "/openshell.v1.OpenShell/DetachSandboxProvider" OpenShell_DeleteSandbox_FullMethodName = "/openshell.v1.OpenShell/DeleteSandbox" + OpenShell_SuspendSandbox_FullMethodName = "/openshell.v1.OpenShell/SuspendSandbox" + OpenShell_ResumeSandbox_FullMethodName = "/openshell.v1.OpenShell/ResumeSandbox" OpenShell_CreateSshSession_FullMethodName = "/openshell.v1.OpenShell/CreateSshSession" OpenShell_ExposeService_FullMethodName = "/openshell.v1.OpenShell/ExposeService" OpenShell_GetService_FullMethodName = "/openshell.v1.OpenShell/GetService" @@ -122,6 +124,10 @@ type OpenShellClient interface { DetachSandboxProvider(ctx context.Context, in *DetachSandboxProviderRequest, opts ...grpc.CallOption) (*DetachSandboxProviderResponse, error) // Delete a sandbox by name. DeleteSandbox(ctx context.Context, in *DeleteSandboxRequest, opts ...grpc.CallOption) (*DeleteSandboxResponse, error) + // Suspend a sandbox while retaining its persistent state. + SuspendSandbox(ctx context.Context, in *SuspendSandboxRequest, opts ...grpc.CallOption) (*SandboxResponse, error) + // Resume a previously suspended sandbox. + ResumeSandbox(ctx context.Context, in *ResumeSandboxRequest, opts ...grpc.CallOption) (*SandboxResponse, error) // Create a short-lived SSH session for a sandbox. CreateSshSession(ctx context.Context, in *CreateSshSessionRequest, opts ...grpc.CallOption) (*CreateSshSessionResponse, error) // Create or update a sandbox HTTP service endpoint for local routing. @@ -379,6 +385,26 @@ func (c *openShellClient) DeleteSandbox(ctx context.Context, in *DeleteSandboxRe return out, nil } +func (c *openShellClient) SuspendSandbox(ctx context.Context, in *SuspendSandboxRequest, opts ...grpc.CallOption) (*SandboxResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SandboxResponse) + err := c.cc.Invoke(ctx, OpenShell_SuspendSandbox_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *openShellClient) ResumeSandbox(ctx context.Context, in *ResumeSandboxRequest, opts ...grpc.CallOption) (*SandboxResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SandboxResponse) + err := c.cc.Invoke(ctx, OpenShell_ResumeSandbox_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *openShellClient) CreateSshSession(ctx context.Context, in *CreateSshSessionRequest, opts ...grpc.CallOption) (*CreateSshSessionResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateSshSessionResponse) @@ -985,6 +1011,10 @@ type OpenShellServer interface { DetachSandboxProvider(context.Context, *DetachSandboxProviderRequest) (*DetachSandboxProviderResponse, error) // Delete a sandbox by name. DeleteSandbox(context.Context, *DeleteSandboxRequest) (*DeleteSandboxResponse, error) + // Suspend a sandbox while retaining its persistent state. + SuspendSandbox(context.Context, *SuspendSandboxRequest) (*SandboxResponse, error) + // Resume a previously suspended sandbox. + ResumeSandbox(context.Context, *ResumeSandboxRequest) (*SandboxResponse, error) // Create a short-lived SSH session for a sandbox. CreateSshSession(context.Context, *CreateSshSessionRequest) (*CreateSshSessionResponse, error) // Create or update a sandbox HTTP service endpoint for local routing. @@ -1172,6 +1202,12 @@ func (UnimplementedOpenShellServer) DetachSandboxProvider(context.Context, *Deta func (UnimplementedOpenShellServer) DeleteSandbox(context.Context, *DeleteSandboxRequest) (*DeleteSandboxResponse, error) { return nil, status.Error(codes.Unimplemented, "method DeleteSandbox not implemented") } +func (UnimplementedOpenShellServer) SuspendSandbox(context.Context, *SuspendSandboxRequest) (*SandboxResponse, error) { + return nil, status.Error(codes.Unimplemented, "method SuspendSandbox not implemented") +} +func (UnimplementedOpenShellServer) ResumeSandbox(context.Context, *ResumeSandboxRequest) (*SandboxResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ResumeSandbox not implemented") +} func (UnimplementedOpenShellServer) CreateSshSession(context.Context, *CreateSshSessionRequest) (*CreateSshSessionResponse, error) { return nil, status.Error(codes.Unimplemented, "method CreateSshSession not implemented") } @@ -1535,6 +1571,42 @@ func _OpenShell_DeleteSandbox_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _OpenShell_SuspendSandbox_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SuspendSandboxRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(OpenShellServer).SuspendSandbox(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: OpenShell_SuspendSandbox_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(OpenShellServer).SuspendSandbox(ctx, req.(*SuspendSandboxRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _OpenShell_ResumeSandbox_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResumeSandboxRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(OpenShellServer).ResumeSandbox(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: OpenShell_ResumeSandbox_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(OpenShellServer).ResumeSandbox(ctx, req.(*ResumeSandboxRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _OpenShell_CreateSshSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateSshSessionRequest) if err := dec(in); err != nil { @@ -2485,6 +2557,14 @@ var OpenShell_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteSandbox", Handler: _OpenShell_DeleteSandbox_Handler, }, + { + MethodName: "SuspendSandbox", + Handler: _OpenShell_SuspendSandbox_Handler, + }, + { + MethodName: "ResumeSandbox", + Handler: _OpenShell_ResumeSandbox_Handler, + }, { MethodName: "CreateSshSession", Handler: _OpenShell_CreateSshSession_Handler,