diff --git a/crates/openshell-cli/tests/ensure_providers_integration.rs b/crates/openshell-cli/tests/ensure_providers_integration.rs index e7221e0079..38b2b6d48d 100644 --- a/crates/openshell-cli/tests/ensure_providers_integration.rs +++ b/crates/openshell-cli/tests/ensure_providers_integration.rs @@ -79,6 +79,13 @@ impl TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/mtls_integration.rs b/crates/openshell-cli/tests/mtls_integration.rs index ca969dde13..1155ef762d 100644 --- a/crates/openshell-cli/tests/mtls_integration.rs +++ b/crates/openshell-cli/tests/mtls_integration.rs @@ -32,6 +32,13 @@ struct TestOpenShell; #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &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 2cbeaffdf6..5d6e8c8190 100644 --- a/crates/openshell-cli/tests/provider_commands_integration.rs +++ b/crates/openshell-cli/tests/provider_commands_integration.rs @@ -232,6 +232,13 @@ impl TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &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 964559a8ad..b2fa432bde 100644 --- a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs +++ b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs @@ -92,6 +92,13 @@ struct TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &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 7a5780d7f3..d8e0e80088 100644 --- a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs +++ b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs @@ -47,6 +47,13 @@ struct TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &self, _request: tonic::Request, diff --git a/crates/openshell-core/src/config.rs b/crates/openshell-core/src/config.rs index 820b4a9476..7057a19b1d 100644 --- a/crates/openshell-core/src/config.rs +++ b/crates/openshell-core/src/config.rs @@ -46,6 +46,30 @@ pub const DEFAULT_DOCKER_NETWORK_NAME: &str = "openshell-docker"; /// Default domain used for browser-facing sandbox service URLs. pub const DEFAULT_SERVICE_ROUTING_DOMAIN: &str = "openshell.localhost"; +/// Gateway delivery path for supervisor configuration. +/// `Push` is a shadow stream until supervisors support applying snapshots. +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum ConfigDeliveryMode { + #[default] + Poll, + Push, +} + +impl FromStr for ConfigDeliveryMode { + type Err = String; + + fn from_str(value: &str) -> Result { + match value { + "poll" => Ok(Self::Poll), + "push" => Ok(Self::Push), + _ => Err(format!( + "invalid config delivery mode '{value}'; expected poll or push" + )), + } + } +} + /// Gateway posture when a sandbox rejects a candidate policy generation. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] @@ -185,6 +209,9 @@ pub struct Config { /// Security posture for rejected sandbox policy generations. pub policy_validation_failure_mode: PolicyValidationFailureMode, + /// Optional shadow push of complete supervisor configuration snapshots. + pub config_delivery_mode: ConfigDeliveryMode, + /// TLS configuration. When `None`, the server listens on plaintext HTTP. pub tls: Option, @@ -851,6 +878,7 @@ impl Config { metrics_bind_address: None, log_level: default_log_level(), policy_validation_failure_mode: PolicyValidationFailureMode::default(), + config_delivery_mode: ConfigDeliveryMode::default(), tls, oidc: None, auth: GatewayAuthConfig::default(), @@ -1116,10 +1144,11 @@ const fn default_ssh_session_ttl_secs() -> u64 { #[cfg(test)] mod tests { use super::{ - AppArmorProfile, Config, DEFAULT_SERVICE_ROUTING_DOMAIN, GatewayInterceptorBindingPolicy, - GatewayInterceptorConfig, GatewayInterceptorFailurePolicy, GatewayJwtConfig, - GatewayProviderProfileSourceConfig, ImagePullPolicy, PolicyValidationFailureMode, - UpstreamProxyConfig, default_sandbox_pids_limit, normalize_compute_driver_name, + AppArmorProfile, Config, ConfigDeliveryMode, DEFAULT_SERVICE_ROUTING_DOMAIN, + GatewayInterceptorBindingPolicy, GatewayInterceptorConfig, GatewayInterceptorFailurePolicy, + GatewayJwtConfig, GatewayProviderProfileSourceConfig, ImagePullPolicy, + PolicyValidationFailureMode, UpstreamProxyConfig, default_sandbox_pids_limit, + normalize_compute_driver_name, }; use std::net::SocketAddr; use std::time::Duration; @@ -1139,6 +1168,19 @@ mod tests { assert!("keep_old".parse::().is_err()); } + #[test] + fn config_delivery_defaults_to_poll_and_rejects_unknown_modes() { + assert_eq!( + Config::new(None).config_delivery_mode, + ConfigDeliveryMode::Poll + ); + assert_eq!( + "push".parse::().unwrap(), + ConfigDeliveryMode::Push + ); + assert!("enabled".parse::().is_err()); + } + #[test] fn compute_driver_name_normalization_accepts_builtin_and_custom_names() { assert_eq!(normalize_compute_driver_name(" VM ").unwrap(), "vm"); diff --git a/crates/openshell-core/src/proto/mod.rs b/crates/openshell-core/src/proto/mod.rs index c6076620a9..3fcfc18d82 100644 --- a/crates/openshell-core/src/proto/mod.rs +++ b/crates/openshell-core/src/proto/mod.rs @@ -99,6 +99,21 @@ pub fn all_workspaces_selector() -> WorkspaceSelector { } } +/// Exact protocol revision required between a gateway and its supervisor. +/// +/// The supervisor stream is an internal, version-locked deployment contract. +/// Bump this when either peer can no longer honor the previous stream +/// semantics. +pub const SUPERVISOR_PROTOCOL_REVISION: u32 = 1; + +/// Revision implied by peers built before the handshake existed. Proto3 leaves +/// the field unset, so such peers report zero. +/// +/// Sandboxes keep their supervisor binary until they are recreated, so a +/// gateway upgrade must keep serving them for one release. Remove this +/// allowance once every supported release sends an explicit revision. +pub const LEGACY_SUPERVISOR_PROTOCOL_REVISION: u32 = 0; + #[cfg(test)] mod tests { use std::collections::HashMap; diff --git a/crates/openshell-sdk/tests/client_mock.rs b/crates/openshell-sdk/tests/client_mock.rs index 9506160f07..e28bfc107f 100644 --- a/crates/openshell-sdk/tests/client_mock.rs +++ b/crates/openshell-sdk/tests/client_mock.rs @@ -229,6 +229,13 @@ fn workload_template_proto(name: &str, workspace: &str) -> proto::SandboxWorkloa #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &self, _request: tonic::Request, diff --git a/crates/openshell-server/src/auth/method_authz.rs b/crates/openshell-server/src/auth/method_authz.rs index 06f6784cc8..544d2197c9 100644 --- a/crates/openshell-server/src/auth/method_authz.rs +++ b/crates/openshell-server/src/auth/method_authz.rs @@ -155,6 +155,7 @@ mod tests { "/openshell.v1.OpenShell/PeerReportProviderReadiness", "/openshell.v1.OpenShell/PeerReportEndpointStatus", "/openshell.v1.OpenShell/PeerGetSandboxProviderStatus", + "/openshell.v1.OpenShell/PeerNotifyConfigUpdate", ] { assert!(!is_user_callable(path)); assert!(is_peer_callable(path)); diff --git a/crates/openshell-server/src/auth/peer.rs b/crates/openshell-server/src/auth/peer.rs index e9053649a8..06911398a4 100644 --- a/crates/openshell-server/src/auth/peer.rs +++ b/crates/openshell-server/src/auth/peer.rs @@ -715,6 +715,7 @@ mod tests { "/openshell.v1.OpenShell/PeerReportProviderReadiness", "/openshell.v1.OpenShell/PeerReportEndpointStatus", "/openshell.v1.OpenShell/PeerGetSandboxProviderStatus", + "/openshell.v1.OpenShell/PeerNotifyConfigUpdate", ] { assert!(matches!( auth.authenticate(&headers, path).await.unwrap(), @@ -727,7 +728,7 @@ mod tests { .unwrap() .is_none() ); - assert_eq!(resolver.seen_tokens.lock().unwrap().len(), 4); + assert_eq!(resolver.seen_tokens.lock().unwrap().len(), 5); } fn identity() -> ResolvedGatewayPeerIdentity { diff --git a/crates/openshell-server/src/cli.rs b/crates/openshell-server/src/cli.rs index 87b67f5e8a..6418ca316a 100644 --- a/crates/openshell-server/src/cli.rs +++ b/crates/openshell-server/src/cli.rs @@ -6,7 +6,7 @@ use clap::parser::ValueSource; use clap::{ArgAction, ArgMatches, Command, CommandFactory, FromArgMatches, Parser}; use miette::{IntoDiagnostic, Result}; -use openshell_core::config::{DEFAULT_GATEWAY_NAME, DEFAULT_SERVER_PORT}; +use openshell_core::config::{ConfigDeliveryMode, DEFAULT_GATEWAY_NAME, DEFAULT_SERVER_PORT}; use std::collections::BTreeMap; use std::ffi::OsString; use std::net::{IpAddr, SocketAddr}; @@ -239,6 +239,10 @@ struct RunArgs { #[arg(long, env = "OPENSHELL_GRPC_RATE_LIMIT_WINDOW_SECONDS")] grpc_rate_limit_window_seconds: Option, + /// Supervisor configuration delivery. Push sends shadow snapshots in this release. + #[arg(long, env = "OPENSHELL_CONFIG_DELIVERY_MODE")] + config_delivery_mode: Option, + /// Subject Alternative Names configured on the gateway server certificate. /// Wildcard DNS SANs also enable sandbox service URLs under that domain. #[arg( @@ -550,6 +554,13 @@ fn prepare_server_config_with_drivers( { config.policy_validation_failure_mode = mode; } + config.config_delivery_mode = args + .config_delivery_mode + .or_else(|| { + file.as_ref() + .and_then(|f| f.openshell.gateway.config_delivery_mode) + }) + .unwrap_or_default(); if let Some(issuer) = args.oidc_issuer.clone() { config = config.with_oidc(openshell_core::OidcConfig { diff --git a/crates/openshell-server/src/compute/mod.rs b/crates/openshell-server/src/compute/mod.rs index 264cd77bbb..53b837c8fd 100644 --- a/crates/openshell-server/src/compute/mod.rs +++ b/crates/openshell-server/src/compute/mod.rs @@ -1100,6 +1100,18 @@ impl ComputeRuntime { } drop(global_guard); + if let Err(status) = Box::pin(crate::grpc::policy::initialize_policy_history( + self.store.as_ref(), + &sandbox, + crate::grpc::policy::InitialPolicyHistoryStatus::Pending, + )) + .await + { + let _ = self.store.delete(Sandbox::object_type(), &sandbox_id).await; + self.sandbox_index.remove_sandbox(&sandbox_id); + return Err(status); + } + if let Some(token) = sandbox_token && let Some(spec) = driver_sandbox.spec.as_mut() { @@ -1178,6 +1190,10 @@ impl ComputeRuntime { Ok(sandbox) } Err(status) if status.code() == Code::AlreadyExists => { + let _ = self + .store + .delete_by_scope(POLICY_OBJECT_TYPE, sandbox.object_id()) + .await; let _ = self .store .delete(Sandbox::object_type(), sandbox.object_id()) @@ -1186,6 +1202,10 @@ impl ComputeRuntime { Err(Status::already_exists("sandbox already exists")) } Err(status) if status.code() == Code::FailedPrecondition => { + let _ = self + .store + .delete_by_scope(POLICY_OBJECT_TYPE, sandbox.object_id()) + .await; let _ = self .store .delete(Sandbox::object_type(), sandbox.object_id()) @@ -1194,6 +1214,10 @@ impl ComputeRuntime { Err(Status::failed_precondition(status.message().to_string())) } Err(err) => { + let _ = self + .store + .delete_by_scope(POLICY_OBJECT_TYPE, sandbox.object_id()) + .await; let _ = self .store .delete(Sandbox::object_type(), sandbox.object_id()) @@ -6941,6 +6965,7 @@ pub fn new_test_runtime_with_driver( #[cfg(test)] mod tests { use super::*; + use crate::policy_store::PolicyStoreExt; use futures::stream; use openshell_core::proto::compute::v1::{ CreateSandboxResponse, DeleteSandboxResponse, GetCapabilitiesResponse, GetSandboxRequest, @@ -15142,6 +15167,36 @@ mod tests { ); } + #[tokio::test] + async fn create_sandbox_persists_initial_policy_revision() { + let runtime = test_runtime(Arc::new(TestDriver::default())).await; + let mut sandbox = sandbox_record( + "sb-initial-policy", + "initial-policy", + SandboxPhase::Provisioning, + ); + let policy = openshell_core::proto::SandboxPolicy::default(); + sandbox.spec = Some(SandboxSpec { + policy: Some(policy.clone()), + ..Default::default() + }); + + runtime.create_sandbox(sandbox, None, false).await.unwrap(); + + let revision = runtime + .store + .get_latest_policy("sb-initial-policy") + .await + .unwrap() + .expect("initial policy revision"); + assert_eq!(revision.version, 1); + assert_eq!( + revision.policy_hash, + crate::grpc::policy::deterministic_policy_hash(&policy) + ); + assert_eq!(revision.status, "pending"); + } + #[tokio::test] async fn created_sandbox_is_immediately_visible_to_label_selectors() { let runtime = test_runtime(Arc::new(TestDriver::default())).await; diff --git a/crates/openshell-server/src/config_delivery.rs b/crates/openshell-server/src/config_delivery.rs new file mode 100644 index 0000000000..a288782139 --- /dev/null +++ b/crates/openshell-server/src/config_delivery.rs @@ -0,0 +1,1417 @@ +// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Build and route complete supervisor configuration snapshots. + +use std::collections::HashMap; +use std::collections::hash_map::Entry; +use std::fmt; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +use futures::StreamExt; +use metrics::counter; +use openshell_core::config::ConfigDeliveryMode; +use openshell_core::proto::{ + ConfigBootstrap, PeerConfigSandboxTarget, PeerConfigUpdateHintRequest, + PeerConfigUpdateHintResponse, ProviderEnvironmentSnapshot, Sandbox, SandboxConfigSnapshot, + peer_config_update_hint_request, +}; +use tokio::sync::{OwnedSemaphorePermit, Semaphore}; +use tonic::{Code, Request, Response, Status}; +use tracing::warn; + +use crate::ServerState; +use crate::auth::principal::Principal; +use crate::grpc::policy::{build_provider_environment_snapshot, build_sandbox_config_snapshot}; +use crate::persistence::ObjectWorkspace; +use crate::supervisor_owner::{OWNER_TTL, SupervisorOwnerIndex}; +use crate::supervisor_session::SupervisorSessionRegistry; + +/// Leaves headroom below tonic's default 4 MiB decode limit for framing and +/// future envelope fields. +pub const MAX_SUPERVISOR_CONFIG_MESSAGE_BYTES: usize = 3 * 1024 * 1024; +const CONFIG_SNAPSHOT_BUILD_TIMEOUT: Duration = Duration::from_secs(45); +// Stage 1 bootstrap is optional. Keep credential backend stalls well below +// the 15-second relay session-wait budget while polling remains authoritative. +const CONFIG_BOOTSTRAP_BUILD_TIMEOUT: Duration = Duration::from_secs(1); +const MAX_ACTIVE_FANOUT_WORKERS: usize = 64; +/// Concurrent snapshot builds allowed per pooled database connection. Builds +/// are short bursts of small queries, so a little oversubscription keeps the +/// pool busy without stacking every waiter on the acquire timeout. +const SNAPSHOT_BUILDS_PER_DB_CONNECTION: usize = 2; +const MIN_CONCURRENT_SNAPSHOT_BUILDS: usize = 4; + +/// One complete configuration component awaiting delivery to a supervisor. +#[derive(Clone)] +pub enum SupervisorConfigMessage { + SandboxConfig(Box), + ProviderEnvironment(ProviderEnvironmentSnapshot), +} + +impl SupervisorConfigMessage { + pub(crate) fn component_name(&self) -> &'static str { + match self { + Self::SandboxConfig(_) => "sandbox_config", + Self::ProviderEnvironment(_) => "provider_environment", + } + } +} + +impl fmt::Debug for SupervisorConfigMessage { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str(match self { + Self::SandboxConfig(_) => "SandboxConfig()", + Self::ProviderEnvironment(_) => "ProviderEnvironment()", + }) + } +} + +/// Result of routing one configuration snapshot toward a supervisor session. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum DeliveryDisposition { + Enqueued, + NoActiveSession, + UnsupportedSession, + QueueFull, + SessionClosed, + PayloadTooLarge, +} + +/// Transport boundary for configuration delivery. +#[tonic::async_trait] +pub trait SupervisorConfigRouter: fmt::Debug + Send + Sync { + async fn deliver( + &self, + sandbox_id: &str, + message: SupervisorConfigMessage, + ) -> DeliveryDisposition; + + async fn routable_sandbox_ids(&self) -> Vec; +} + +#[derive(Debug)] +pub struct LocalSupervisorConfigRouter { + sessions: Arc, +} + +impl LocalSupervisorConfigRouter { + #[must_use] + pub fn new(sessions: Arc) -> Self { + Self { sessions } + } +} + +#[tonic::async_trait] +impl SupervisorConfigRouter for LocalSupervisorConfigRouter { + async fn deliver( + &self, + sandbox_id: &str, + message: SupervisorConfigMessage, + ) -> DeliveryDisposition { + self.sessions.deliver_config(sandbox_id, message) + } + + async fn routable_sandbox_ids(&self) -> Vec { + self.sessions.connected_sandbox_ids() + } +} + +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] +pub struct ConfigComponents { + pub sandbox_config: bool, + pub provider_environment: bool, +} + +impl ConfigComponents { + pub const ALL: Self = Self { + sandbox_config: true, + provider_environment: true, + }; + + pub const SANDBOX_AND_PROVIDER: Self = Self { + sandbox_config: true, + provider_environment: true, + }; + + pub const SANDBOX_CONFIG: Self = Self { + sandbox_config: true, + provider_environment: false, + }; + + fn selected(self) -> impl Iterator { + [ + (self.sandbox_config, ConfigComponentKind::SandboxConfig), + ( + self.provider_environment, + ConfigComponentKind::ProviderEnvironment, + ), + ] + .into_iter() + .filter_map(|(selected, component)| selected.then_some(component)) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum ConfigComponentKind { + SandboxConfig, + ProviderEnvironment, +} + +impl ConfigComponentKind { + fn name(self) -> &'static str { + match self { + Self::SandboxConfig => "sandbox_config", + Self::ProviderEnvironment => "provider_environment", + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct DeliveryKey { + sandbox_id: String, + component: ConfigComponentKind, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +enum FanoutScope { + Workspace(String), + AllConnected, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct FanoutKey { + scope: FanoutScope, + component: ConfigComponentKind, + route_remote: bool, +} + +/// Coalesces publications and bounds workers per sandbox and component. +/// +/// The map entry is also the worker lease. Its boolean is set when another +/// mutation arrives during a build or route operation. The worker then rebuilds +/// the current full snapshot once, regardless of how many mutations arrived. +/// +/// Each pending map entry owns a delivery permit for its worker. Direct +/// publications fail fast when all permits are held. Fanout workers wait for a +/// permit before admitting the next recipient, which bounds both spawned tasks +/// and pending keys while still walking the full recipient list. +#[derive(Debug)] +pub struct ConfigDeliveryQueue { + pending: Mutex>, + fanout_pending: Mutex>, + delivery_permits: Arc, + build_permits: Semaphore, +} + +impl Default for ConfigDeliveryQueue { + fn default() -> Self { + Self::new(MIN_CONCURRENT_SNAPSHOT_BUILDS) + } +} + +impl ConfigDeliveryQueue { + #[must_use] + pub fn new(max_concurrent_builds: usize) -> Self { + let max_concurrent_builds = max_concurrent_builds.max(1); + Self { + pending: Mutex::default(), + fanout_pending: Mutex::default(), + delivery_permits: Arc::new(Semaphore::new(max_concurrent_builds)), + build_permits: Semaphore::new(max_concurrent_builds), + } + } + + /// Size the build bound from the persistence pool that every build reads. + #[must_use] + pub fn for_db_connections(max_connections: u32) -> Self { + let max_connections = usize::try_from(max_connections).unwrap_or(usize::MAX); + Self::new( + max_connections + .saturating_mul(SNAPSHOT_BUILDS_PER_DB_CONNECTION) + .max(MIN_CONCURRENT_SNAPSHOT_BUILDS), + ) + } + + #[cfg(test)] + fn max_concurrent_builds(&self) -> usize { + self.build_permits.available_permits() + } + + /// Run one snapshot build under the concurrency bound. The deadline starts + /// only once a permit is held so queued builds do not spend their budget + /// waiting. + async fn run_bounded_build( + &self, + build: impl Future, + ) -> Result { + let _permit = self + .build_permits + .acquire() + .await + .expect("snapshot build semaphore is never closed"); + tokio::time::timeout(CONFIG_SNAPSHOT_BUILD_TIMEOUT, build).await + } + + fn enqueue(&self, key: DeliveryKey) -> DeliveryEnqueue { + let mut pending = self.pending.lock().unwrap(); + match pending.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() = true; + DeliveryEnqueue::Coalesced + } + Entry::Vacant(entry) => { + let Ok(permit) = Arc::clone(&self.delivery_permits).try_acquire_owned() else { + return DeliveryEnqueue::Full; + }; + entry.insert(true); + DeliveryEnqueue::StartWorker(permit) + } + } + } + + async fn enqueue_from_fanout(&self, key: DeliveryKey) -> DeliveryEnqueue { + { + let mut pending = self.pending.lock().unwrap(); + if let Entry::Occupied(mut entry) = pending.entry(key.clone()) { + *entry.get_mut() = true; + return DeliveryEnqueue::Coalesced; + } + } + + let permit = Arc::clone(&self.delivery_permits) + .acquire_owned() + .await + .expect("delivery worker semaphore is never closed"); + let mut pending = self.pending.lock().unwrap(); + match pending.entry(key) { + Entry::Occupied(mut entry) => { + *entry.get_mut() = true; + DeliveryEnqueue::Coalesced + } + Entry::Vacant(entry) => { + entry.insert(true); + DeliveryEnqueue::StartWorker(permit) + } + } + } + + fn take(&self, key: &DeliveryKey) { + let mut pending = self.pending.lock().unwrap(); + if let Some(changed) = pending.get_mut(key) { + *changed = false; + } + } + + fn finish_pass(&self, key: &DeliveryKey) -> bool { + let mut pending = self.pending.lock().unwrap(); + if pending.get(key).is_some_and(|changed| !changed) { + pending.remove(key); + false + } else { + pending.contains_key(key) + } + } + + fn enqueue_fanout(&self, key: FanoutKey) -> FanoutEnqueue { + let mut pending = self.fanout_pending.lock().unwrap(); + if let Some(changed) = pending.get_mut(&key) { + *changed = true; + return FanoutEnqueue::Coalesced; + } + if pending.len() >= MAX_ACTIVE_FANOUT_WORKERS { + FanoutEnqueue::Full + } else { + pending.insert(key, true); + FanoutEnqueue::StartWorker + } + } + + fn take_fanout(&self, key: &FanoutKey) { + let mut pending = self.fanout_pending.lock().unwrap(); + if let Some(changed) = pending.get_mut(key) { + *changed = false; + } + } + + fn finish_fanout_pass(&self, key: &FanoutKey) -> bool { + let mut pending = self.fanout_pending.lock().unwrap(); + if pending.get(key).is_some_and(|changed| !changed) { + pending.remove(key); + false + } else { + pending.contains_key(key) + } + } +} + +#[derive(Debug)] +enum DeliveryEnqueue { + StartWorker(OwnedSemaphorePermit), + Coalesced, + Full, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum FanoutEnqueue { + StartWorker, + Coalesced, + Full, +} + +pub async fn build_config_bootstrap( + state: &Arc, + sandbox: &Sandbox, +) -> Result { + tokio::time::timeout( + CONFIG_BOOTSTRAP_BUILD_TIMEOUT, + build_consistent_config_bootstrap(state, sandbox), + ) + .await + .map_err(|_| Status::deadline_exceeded("supervisor configuration bootstrap timed out"))? +} + +async fn build_consistent_config_bootstrap( + state: &Arc, + sandbox: &Sandbox, +) -> Result { + const MAX_BUILD_ATTEMPTS: usize = 3; + for _ in 0..MAX_BUILD_ATTEMPTS { + // Components are independent projections. The provider revision is a + // fence for the only overlapping input between sandbox configuration + // and provider environment state. + let (sandbox_config, provider_environment) = tokio::join!( + build_sandbox_config_snapshot(state, sandbox), + build_provider_environment_snapshot(state, sandbox, true), + ); + let bootstrap = ConfigBootstrap { + sandbox_config: Some(sandbox_config?), + provider_environment: Some(provider_environment?), + }; + if bootstrap_revisions_match(&bootstrap) { + return Ok(bootstrap); + } + counter!("openshell_supervisor_config_bootstrap_revision_mismatches_total").increment(1); + } + Err(Status::aborted( + "configuration changed while building supervisor bootstrap", + )) +} + +fn bootstrap_revisions_match(bootstrap: &ConfigBootstrap) -> bool { + bootstrap + .sandbox_config + .as_ref() + .zip(bootstrap.provider_environment.as_ref()) + .is_some_and(|(sandbox, provider)| { + sandbox.provider_env_revision == provider.provider_env_revision + }) +} + +pub fn publish_sandbox_components( + state: &Arc, + sandbox_id: &str, + components: ConfigComponents, +) { + if state.config.config_delivery_mode != ConfigDeliveryMode::Push { + return; + } + enqueue_sandbox(state, sandbox_id, components); +} + +fn enqueue_sandbox( + state: &Arc, + sandbox_id: &str, + components: ConfigComponents, +) -> bool { + let mut accepted = true; + for component in components.selected() { + let key = DeliveryKey { + sandbox_id: sandbox_id.to_string(), + component, + }; + match state.config_delivery_queue.enqueue(key.clone()) { + DeliveryEnqueue::StartWorker(permit) => { + spawn_delivery_worker(state, key, permit); + } + DeliveryEnqueue::Coalesced => {} + DeliveryEnqueue::Full => { + accepted = false; + record_delivery_worker_full(sandbox_id, component.name()); + } + } + } + accepted +} + +fn spawn_delivery_worker(state: &Arc, key: DeliveryKey, permit: OwnedSemaphorePermit) { + let state = Arc::clone(state); + tokio::spawn(async move { + let _permit = permit; + loop { + state.config_delivery_queue.take(&key); + publish_sandbox_component_now(&state, &key).await; + if !state.config_delivery_queue.finish_pass(&key) { + break; + } + } + }); +} + +async fn enqueue_sandbox_from_fanout( + state: &Arc, + sandbox_id: &str, + component: ConfigComponentKind, +) { + let key = DeliveryKey { + sandbox_id: sandbox_id.to_string(), + component, + }; + match state + .config_delivery_queue + .enqueue_from_fanout(key.clone()) + .await + { + DeliveryEnqueue::StartWorker(permit) => spawn_delivery_worker(state, key, permit), + DeliveryEnqueue::Coalesced => {} + DeliveryEnqueue::Full => unreachable!("fanout waits for delivery worker capacity"), + } +} + +async fn publish_sandbox_component_now(state: &Arc, key: &DeliveryKey) { + if route_remote_sandbox_component(state, key).await { + return; + } + if !is_current_local_owner(state, &key.sandbox_id).await { + return; + } + if !state + .supervisor_sessions + .is_config_push_capable(&key.sandbox_id) + { + return; + } + let component = key.component.name(); + let build = async { + let sandbox = state + .store + .get_message::(&key.sandbox_id) + .await + .map_err(|error| Status::internal(format!("fetch sandbox failed: {error}")))?; + let Some(sandbox) = sandbox else { + return Ok(None); + }; + match key.component { + ConfigComponentKind::SandboxConfig => build_sandbox_config_snapshot(state, &sandbox) + .await + .map(|snapshot| SupervisorConfigMessage::SandboxConfig(Box::new(snapshot))), + ConfigComponentKind::ProviderEnvironment => { + build_provider_environment_snapshot(state, &sandbox, true) + .await + .map(SupervisorConfigMessage::ProviderEnvironment) + } + } + .map(Some) + }; + match state.config_delivery_queue.run_bounded_build(build).await { + Ok(Ok(None)) => {} + Ok(Ok(Some(message))) => { + if !is_current_local_owner(state, &key.sandbox_id).await { + return; + } + let disposition = state + .supervisor_config_router() + .deliver(&key.sandbox_id, message) + .await; + record_delivery(component, disposition); + } + Ok(Err(error)) => { + record_build_failure(&key.sandbox_id, component, error.code()); + } + Err(_) => { + record_build_failure(&key.sandbox_id, component, Code::DeadlineExceeded); + } + } +} + +async fn is_current_local_owner(state: &Arc, sandbox_id: &str) -> bool { + let owners = SupervisorOwnerIndex::new(Arc::clone(&state.store), OWNER_TTL); + match owners.read(sandbox_id).await { + Ok(Some(owner)) => { + owner.is_fresh(OWNER_TTL) + && owner.owner_replica_id == state.replica_id + && state + .supervisor_sessions + .is_current_session(sandbox_id, &owner.session_id) + } + Ok(None) => false, + Err(error) => { + warn!(sandbox_id, error = %error, "configuration owner lookup failed"); + false + } + } +} + +/// Return true when the current owner is remote or the session is gone. +/// The owner builds its own snapshot after receiving this secret-free hint. +async fn route_remote_sandbox_component(state: &Arc, key: &DeliveryKey) -> bool { + let owners = SupervisorOwnerIndex::new(Arc::clone(&state.store), OWNER_TTL); + let mut final_outcome = "stale_owner"; + for attempt in 0..2 { + let owner = match owners.read(&key.sandbox_id).await { + Ok(Some(owner)) if owner.is_fresh(OWNER_TTL) => owner, + Ok(_) => return true, + Err(error) => { + warn!(sandbox_id = %key.sandbox_id, error = %error, "configuration owner lookup failed"); + return true; + } + }; + if owner.owner_replica_id == state.replica_id { + return !state + .supervisor_sessions + .is_current_session(&key.sandbox_id, &owner.session_id); + } + if !owner.owner_peer_endpoint.starts_with("http://") + && !owner.owner_peer_endpoint.starts_with("https://") + { + warn!(sandbox_id = %key.sandbox_id, owner = %owner.owner_replica_id, "configuration owner has no reachable peer endpoint"); + return true; + } + let request = PeerConfigUpdateHintRequest { + scope: Some(peer_config_update_hint_request::Scope::Sandbox( + PeerConfigSandboxTarget { + sandbox_id: key.sandbox_id.clone(), + session_id: owner.session_id, + }, + )), + sandbox_config: key.component == ConfigComponentKind::SandboxConfig, + provider_environment: key.component == ConfigComponentKind::ProviderEnvironment, + }; + let result = tokio::time::timeout( + Duration::from_secs(5), + crate::supervisor_session::forward_config_hint_to_peer( + state, + &owner.owner_peer_endpoint, + request, + ), + ) + .await; + match result { + Ok(Ok(response)) if !response.stale_owner && !response.queue_full => { + counter!("openshell_supervisor_config_peer_hints_total", "outcome" => "accepted") + .increment(1); + return true; + } + Ok(Ok(response)) if response.queue_full => { + counter!("openshell_supervisor_config_peer_hints_total", "outcome" => "queue_full") + .increment(1); + return true; + } + Ok(Err(error)) if error.code() == Code::Unimplemented => { + counter!("openshell_supervisor_config_peer_hints_total", "outcome" => "unsupported_peer") + .increment(1); + return true; + } + Ok(Err(error)) => { + final_outcome = "peer_error"; + warn!(sandbox_id = %key.sandbox_id, owner = %owner.owner_replica_id, attempt, code = ?error.code(), "configuration peer hint failed"); + } + Err(_) => { + final_outcome = "timeout"; + warn!(sandbox_id = %key.sandbox_id, owner = %owner.owner_replica_id, attempt, "configuration peer hint timed out"); + } + Ok(Ok(_)) => final_outcome = "stale_owner", + } + } + counter!("openshell_supervisor_config_peer_hints_total", "outcome" => final_outcome) + .increment(1); + true +} + +pub fn publish_workspace_components( + state: &Arc, + workspace: &str, + components: ConfigComponents, +) { + if state.config.config_delivery_mode != ConfigDeliveryMode::Push { + return; + } + enqueue_fanout( + state, + FanoutScope::Workspace(workspace.to_string()), + components, + true, + ); +} + +pub fn publish_all_connected(state: &Arc, components: ConfigComponents) { + if state.config.config_delivery_mode != ConfigDeliveryMode::Push { + return; + } + enqueue_fanout(state, FanoutScope::AllConnected, components, true); +} + +fn enqueue_fanout( + state: &Arc, + scope: FanoutScope, + components: ConfigComponents, + route_remote: bool, +) -> bool { + let mut accepted = true; + for component in components.selected() { + let key = FanoutKey { + scope: scope.clone(), + component, + route_remote, + }; + match state.config_delivery_queue.enqueue_fanout(key.clone()) { + FanoutEnqueue::StartWorker => { + let state = Arc::clone(state); + tokio::spawn(async move { + loop { + state.config_delivery_queue.take_fanout(&key); + publish_fanout_now(&state, &key).await; + if !state.config_delivery_queue.finish_fanout_pass(&key) { + break; + } + } + }); + } + FanoutEnqueue::Coalesced => {} + FanoutEnqueue::Full => { + accepted = false; + counter!("openshell_supervisor_config_fanout_total", "outcome" => "queue_full") + .increment(1); + warn!( + component = component.name(), + "supervisor configuration fanout queue is full" + ); + } + } + } + accepted +} + +async fn publish_fanout_now(state: &Arc, key: &FanoutKey) { + if key.route_remote { + notify_remote_fanout(state, key).await; + } + let sandbox_ids = state + .supervisor_config_router() + .routable_sandbox_ids() + .await; + for sandbox_id in sandbox_ids { + if let FanoutScope::Workspace(workspace) = &key.scope { + let sandbox = match state.store.get_message::(&sandbox_id).await { + Ok(Some(sandbox)) => sandbox, + Ok(None) => continue, + Err(_) => { + record_build_failure(&sandbox_id, "sandbox", Code::Internal); + continue; + } + }; + if sandbox.object_workspace() != workspace { + continue; + } + } + enqueue_sandbox_from_fanout(state, &sandbox_id, key.component).await; + } +} + +async fn notify_remote_fanout(state: &Arc, key: &FanoutKey) { + let owners = SupervisorOwnerIndex::new(Arc::clone(&state.store), OWNER_TTL); + let endpoints = match owners.list_fresh_peer_endpoints(&state.replica_id).await { + Ok(endpoints) => endpoints, + Err(error) => { + warn!(error = %error, "configuration peer fanout owner listing failed"); + return; + } + }; + futures::stream::iter(endpoints) + .for_each_concurrent(8, |endpoint| async move { + let scope = match &key.scope { + FanoutScope::Workspace(workspace) => { + peer_config_update_hint_request::Scope::Workspace(workspace.clone()) + } + FanoutScope::AllConnected => { + peer_config_update_hint_request::Scope::AllConnected(true) + } + }; + let request = PeerConfigUpdateHintRequest { + scope: Some(scope), + sandbox_config: key.component == ConfigComponentKind::SandboxConfig, + provider_environment: key.component == ConfigComponentKind::ProviderEnvironment, + }; + let result = tokio::time::timeout( + Duration::from_secs(5), + crate::supervisor_session::forward_config_hint_to_peer(state, &endpoint, request), + ) + .await; + match result { + Ok(Ok(response)) if !response.queue_full => { + counter!("openshell_supervisor_config_peer_hints_total", "outcome" => "accepted") + .increment(1); + } + Ok(Ok(_)) => { + counter!("openshell_supervisor_config_peer_hints_total", "outcome" => "queue_full") + .increment(1); + } + Ok(Err(error)) => { + warn!(endpoint = %endpoint, code = ?error.code(), "configuration peer fanout hint failed"); + } + Err(_) => { + warn!(endpoint = %endpoint, "configuration peer fanout hint timed out"); + } + } + }) + .await; +} + +pub async fn handle_peer_config_update_hint( + state: &Arc, + request: Request, +) -> Result, Status> { + if !matches!( + request.extensions().get::(), + Some(Principal::Peer(_)) + ) { + return Err(Status::permission_denied("gateway peer principal required")); + } + if state.config.config_delivery_mode != ConfigDeliveryMode::Push { + return Err(Status::failed_precondition( + "configuration push is disabled", + )); + } + let hint = request.into_inner(); + let components = ConfigComponents { + sandbox_config: hint.sandbox_config, + provider_environment: hint.provider_environment, + }; + if !components.sandbox_config && !components.provider_environment { + return Err(Status::invalid_argument( + "at least one configuration component is required", + )); + } + let mut response = PeerConfigUpdateHintResponse::default(); + match hint.scope { + Some(peer_config_update_hint_request::Scope::Sandbox(target)) => { + if target.sandbox_id.is_empty() || target.session_id.is_empty() { + return Err(Status::invalid_argument( + "sandbox and session IDs are required", + )); + } + let owners = SupervisorOwnerIndex::new(Arc::clone(&state.store), OWNER_TTL); + let owner = owners + .read(&target.sandbox_id) + .await + .map_err(|_| Status::unavailable("configuration owner lookup failed"))?; + response.stale_owner = owner.is_none_or(|owner| { + !owner.is_fresh(OWNER_TTL) + || owner.owner_replica_id != state.replica_id + || owner.session_id != target.session_id + || !state + .supervisor_sessions + .is_current_session(&target.sandbox_id, &target.session_id) + }); + if !response.stale_owner { + response.queue_full = !enqueue_sandbox(state, &target.sandbox_id, components); + } + } + Some(peer_config_update_hint_request::Scope::Workspace(workspace)) => { + if workspace.is_empty() { + return Err(Status::invalid_argument("workspace is required")); + } + response.queue_full = + !enqueue_fanout(state, FanoutScope::Workspace(workspace), components, false); + } + Some(peer_config_update_hint_request::Scope::AllConnected(true)) => { + response.queue_full = + !enqueue_fanout(state, FanoutScope::AllConnected, components, false); + } + _ => { + return Err(Status::invalid_argument( + "configuration hint scope is required", + )); + } + } + Ok(Response::new(response)) +} + +fn record_delivery_worker_full(sandbox_id: &str, component: &'static str) { + counter!( + "openshell_supervisor_config_delivery_workers_total", + "outcome" => "queue_full", + ) + .increment(1); + warn!( + sandbox_id, + component, "supervisor configuration delivery worker queue is full" + ); +} + +fn record_delivery(component: &'static str, disposition: DeliveryDisposition) { + let outcome = match disposition { + DeliveryDisposition::Enqueued => "enqueued", + DeliveryDisposition::NoActiveSession => "no_active_session", + DeliveryDisposition::UnsupportedSession => "unsupported_session", + DeliveryDisposition::QueueFull => "queue_full", + DeliveryDisposition::SessionClosed => "session_closed", + DeliveryDisposition::PayloadTooLarge => "payload_too_large", + }; + counter!( + "openshell_supervisor_config_deliveries_total", + "component" => component, + "outcome" => outcome, + ) + .increment(1); +} + +fn record_build_failure(sandbox_id: &str, component: &'static str, error_code: Code) { + counter!( + "openshell_supervisor_config_snapshot_failures_total", + "component" => component, + ) + .increment(1); + warn!( + sandbox_id = %sandbox_id, + component, + ?error_code, + "failed to build supervisor configuration snapshot" + ); +} + +#[cfg(test)] +mod tests { + use std::sync::atomic::{AtomicUsize, Ordering}; + + use super::*; + use crate::grpc::test_support::{connect_supervisor_stream, test_server_state}; + use openshell_core::proto::{GatewayMessage, ObjectMeta, SandboxSpec, gateway_message}; + + fn peer_hint(sandbox_id: &str, session_id: &str) -> Request { + let mut request = Request::new(PeerConfigUpdateHintRequest { + scope: Some(peer_config_update_hint_request::Scope::Sandbox( + PeerConfigSandboxTarget { + sandbox_id: sandbox_id.into(), + session_id: session_id.into(), + }, + )), + sandbox_config: true, + provider_environment: false, + }); + request + .extensions_mut() + .insert(Principal::Peer(crate::auth::principal::PeerPrincipal { + replica_id: "other-replica".into(), + pod_uid: "peer-pod".into(), + })); + request + } + + #[tokio::test] + async fn peer_hint_requires_push_and_current_session() { + let mut state = test_server_state().await; + let error = handle_peer_config_update_hint(&state, peer_hint("sandbox", "old-session")) + .await + .unwrap_err(); + assert_eq!(error.code(), Code::FailedPrecondition); + + Arc::get_mut(&mut state) + .unwrap() + .config + .config_delivery_mode = ConfigDeliveryMode::Push; + let response = handle_peer_config_update_hint(&state, peer_hint("sandbox", "old-session")) + .await + .unwrap() + .into_inner(); + assert!(response.stale_owner); + assert!(!response.queue_full); + + let error = handle_peer_config_update_hint( + &state, + Request::new(PeerConfigUpdateHintRequest::default()), + ) + .await + .unwrap_err(); + assert_eq!(error.code(), Code::PermissionDenied); + } + + #[tokio::test] + async fn peer_hint_rebuilds_snapshot_on_the_session_owner() { + let mut state = test_server_state().await; + Arc::get_mut(&mut state) + .unwrap() + .config + .config_delivery_mode = ConfigDeliveryMode::Push; + state + .store + .put_message(&Sandbox { + metadata: Some(ObjectMeta { + id: "owned-sandbox".into(), + name: "owned-sandbox".into(), + workspace: "default".into(), + ..Default::default() + }), + spec: Some(SandboxSpec::default()), + ..Default::default() + }) + .await + .unwrap(); + + let mut harness = connect_supervisor_stream( + &state, + "owned-sandbox", + openshell_core::proto::SUPERVISOR_PROTOCOL_REVISION, + ) + .await + .unwrap(); + let accepted = harness.inbound.message().await.unwrap().unwrap(); + let Some(gateway_message::Payload::SessionAccepted(accepted)) = accepted.payload else { + panic!("expected SessionAccepted"); + }; + let response = handle_peer_config_update_hint( + &state, + peer_hint("owned-sandbox", &accepted.session_id), + ) + .await + .unwrap() + .into_inner(); + assert!(!response.stale_owner && !response.queue_full); + let update = tokio::time::timeout(Duration::from_secs(5), harness.inbound.message()) + .await + .unwrap() + .unwrap() + .unwrap(); + assert!(matches!( + update.payload, + Some(gateway_message::Payload::ConfigUpdate(_)) + )); + } + + fn key(sandbox_id: &str, component: ConfigComponentKind) -> DeliveryKey { + DeliveryKey { + sandbox_id: sandbox_id.to_string(), + component, + } + } + + #[test] + fn queue_coalesces_repeated_component_changes_while_worker_is_active() { + let queue = ConfigDeliveryQueue::default(); + let key = key("sb-1", ConfigComponentKind::SandboxConfig); + let DeliveryEnqueue::StartWorker(permit) = queue.enqueue(key.clone()) else { + panic!("first publication must start a worker"); + }; + queue.take(&key); + assert!(matches!( + queue.enqueue(key.clone()), + DeliveryEnqueue::Coalesced + )); + assert!(matches!( + queue.enqueue(key.clone()), + DeliveryEnqueue::Coalesced + )); + assert!(queue.finish_pass(&key)); + queue.take(&key); + assert!(!queue.finish_pass(&key)); + drop(permit); + } + + #[tokio::test] + async fn direct_and_fanout_updates_share_one_component_worker() { + let queue = ConfigDeliveryQueue::default(); + let key = key("sb-1", ConfigComponentKind::SandboxConfig); + let DeliveryEnqueue::StartWorker(permit) = queue.enqueue(key.clone()) else { + panic!("direct update must start a worker"); + }; + queue.take(&key); + assert!(matches!( + queue.enqueue_from_fanout(key.clone()).await, + DeliveryEnqueue::Coalesced + )); + assert!(queue.finish_pass(&key)); + queue.take(&key); + assert!(!queue.finish_pass(&key)); + drop(permit); + } + + #[test] + fn build_bound_is_sized_from_the_database_pool() { + assert_eq!( + ConfigDeliveryQueue::for_db_connections(10).max_concurrent_builds(), + 20 + ); + assert_eq!( + ConfigDeliveryQueue::for_db_connections(1).max_concurrent_builds(), + MIN_CONCURRENT_SNAPSHOT_BUILDS + ); + assert_eq!(ConfigDeliveryQueue::new(0).max_concurrent_builds(), 1); + } + + #[tokio::test(start_paused = true)] + async fn bounded_builds_never_exceed_the_permit_count() { + const PERMITS: usize = 4; + const BUILDS: usize = 40; + let queue = Arc::new(ConfigDeliveryQueue::new(PERMITS)); + let active = Arc::new(AtomicUsize::new(0)); + let peak = Arc::new(AtomicUsize::new(0)); + + let workers = (0..BUILDS) + .map(|_| { + let queue = Arc::clone(&queue); + let active = Arc::clone(&active); + let peak = Arc::clone(&peak); + tokio::spawn(async move { + queue + .run_bounded_build(async { + let now = active.fetch_add(1, Ordering::SeqCst) + 1; + peak.fetch_max(now, Ordering::SeqCst); + tokio::time::sleep(Duration::from_millis(50)).await; + active.fetch_sub(1, Ordering::SeqCst); + }) + .await + .expect("build must not time out"); + }) + }) + .collect::>(); + for worker in workers { + worker.await.unwrap(); + } + + assert_eq!(peak.load(Ordering::SeqCst), PERMITS); + assert_eq!(active.load(Ordering::SeqCst), 0); + assert_eq!(queue.max_concurrent_builds(), PERMITS); + } + + #[tokio::test(start_paused = true)] + async fn build_deadline_starts_after_a_permit_is_held() { + let queue = Arc::new(ConfigDeliveryQueue::new(1)); + let almost_deadline = CONFIG_SNAPSHOT_BUILD_TIMEOUT + .checked_sub(Duration::from_secs(1)) + .unwrap(); + let first = { + let queue = Arc::clone(&queue); + tokio::spawn(async move { + queue + .run_bounded_build(tokio::time::sleep(almost_deadline)) + .await + }) + }; + tokio::task::yield_now().await; + let second = queue.run_bounded_build(tokio::time::sleep(almost_deadline)); + + let (first, second) = tokio::join!(first, second); + assert!(first.unwrap().is_ok()); + assert!( + second.is_ok(), + "waiting for a permit must not consume the build deadline" + ); + + assert!( + queue + .run_bounded_build(tokio::time::sleep( + CONFIG_SNAPSHOT_BUILD_TIMEOUT + Duration::from_secs(1), + )) + .await + .is_err() + ); + } + + #[test] + fn queue_runs_components_and_sandboxes_independently() { + let queue = ConfigDeliveryQueue::new(3); + assert!(matches!( + queue.enqueue(key("sb-1", ConfigComponentKind::SandboxConfig)), + DeliveryEnqueue::StartWorker(_) + )); + assert!(matches!( + queue.enqueue(key("sb-1", ConfigComponentKind::ProviderEnvironment)), + DeliveryEnqueue::StartWorker(_) + )); + assert!(matches!( + queue.enqueue(key("sb-2", ConfigComponentKind::SandboxConfig)), + DeliveryEnqueue::StartWorker(_) + )); + } + + #[tokio::test] + async fn fleet_fanout_waits_without_creating_unbounded_delivery_workers() { + const ROUTED_SANDBOXES: usize = 10_000; + let queue = Arc::new(ConfigDeliveryQueue::new(1)); + let first = key("sandbox-0", ConfigComponentKind::SandboxConfig); + let DeliveryEnqueue::StartWorker(_blocked_worker) = queue.enqueue(first) else { + panic!("first publication must start a worker"); + }; + + let sandbox_ids = (1..ROUTED_SANDBOXES) + .map(|index| format!("sandbox-{index}")) + .collect::>(); + let fanout = async { + for sandbox_id in sandbox_ids { + for component in ConfigComponents::ALL.selected() { + let _ = queue.enqueue_from_fanout(key(&sandbox_id, component)).await; + } + } + }; + tokio::pin!(fanout); + tokio::select! { + () = &mut fanout => panic!("fanout must wait for worker capacity"), + () = tokio::task::yield_now() => {} + } + + assert_eq!(queue.pending.lock().unwrap().len(), 1); + } + + #[test] + fn fanout_queue_coalesces_and_bounds_distinct_scopes() { + let queue = ConfigDeliveryQueue::default(); + let first = FanoutKey { + scope: FanoutScope::Workspace("workspace-0".into()), + component: ConfigComponentKind::SandboxConfig, + route_remote: true, + }; + assert_eq!( + queue.enqueue_fanout(first.clone()), + FanoutEnqueue::StartWorker + ); + queue.take_fanout(&first); + assert_eq!( + queue.enqueue_fanout(first.clone()), + FanoutEnqueue::Coalesced + ); + assert!(queue.finish_fanout_pass(&first)); + + for index in 1..MAX_ACTIVE_FANOUT_WORKERS { + assert_eq!( + queue.enqueue_fanout(FanoutKey { + scope: FanoutScope::Workspace(format!("workspace-{index}")), + component: ConfigComponentKind::SandboxConfig, + route_remote: true, + }), + FanoutEnqueue::StartWorker + ); + } + assert_eq!( + queue.enqueue_fanout(FanoutKey { + scope: FanoutScope::Workspace("overflow".into()), + component: ConfigComponentKind::SandboxConfig, + route_remote: true, + }), + FanoutEnqueue::Full + ); + } + + #[test] + fn configuration_message_debug_output_redacts_payloads() { + let message = SupervisorConfigMessage::ProviderEnvironment(ProviderEnvironmentSnapshot { + values: vec![openshell_core::proto::ProviderEnvironmentValue { + name: "TOKEN".into(), + value: "secret-marker".into(), + ..Default::default() + }], + ..Default::default() + }); + assert!(!format!("{message:?}").contains("secret-marker")); + } + + #[tokio::test] + async fn session_acceptance_precedes_live_configuration_updates() { + let mut state = test_server_state().await; + Arc::get_mut(&mut state) + .unwrap() + .config + .config_delivery_mode = ConfigDeliveryMode::Push; + state + .store + .put_message(&Sandbox { + metadata: Some(ObjectMeta { + id: "sandbox".into(), + name: "sandbox".into(), + workspace: "default".into(), + ..Default::default() + }), + spec: Some(SandboxSpec::default()), + ..Default::default() + }) + .await + .unwrap(); + + let mut harness = connect_supervisor_stream( + &state, + "sandbox", + openshell_core::proto::SUPERVISOR_PROTOCOL_REVISION, + ) + .await + .unwrap(); + + let first = tokio::time::timeout(Duration::from_secs(5), harness.inbound.message()) + .await + .unwrap() + .unwrap() + .unwrap(); + assert!(matches!( + first.payload, + Some(gateway_message::Payload::SessionAccepted(_)) + )); + + publish_sandbox_components(&state, "sandbox", ConfigComponents::SANDBOX_CONFIG); + let update = tokio::time::timeout(Duration::from_secs(5), harness.inbound.message()) + .await + .unwrap() + .unwrap() + .unwrap(); + assert!(matches!( + update, + GatewayMessage { + payload: Some(gateway_message::Payload::ConfigUpdate(_)) + } + )); + } + + #[tokio::test] + async fn legacy_supervisor_keeps_polling_when_gateway_shadow_push_is_enabled() { + let mut state = test_server_state().await; + Arc::get_mut(&mut state) + .unwrap() + .config + .config_delivery_mode = ConfigDeliveryMode::Push; + state + .store + .put_message(&Sandbox { + metadata: Some(ObjectMeta { + id: "legacy-sandbox".into(), + name: "legacy-sandbox".into(), + workspace: "default".into(), + ..Default::default() + }), + spec: Some(SandboxSpec::default()), + ..Default::default() + }) + .await + .unwrap(); + let mut harness = connect_supervisor_stream( + &state, + "legacy-sandbox", + openshell_core::proto::LEGACY_SUPERVISOR_PROTOCOL_REVISION, + ) + .await + .unwrap(); + let first = harness.inbound.message().await.unwrap().unwrap(); + let Some(gateway_message::Payload::SessionAccepted(accepted)) = first.payload else { + panic!("expected SessionAccepted"); + }; + assert!(accepted.bootstrap.is_none()); + publish_sandbox_components(&state, "legacy-sandbox", ConfigComponents::SANDBOX_CONFIG); + assert!( + tokio::time::timeout(Duration::from_millis(100), harness.inbound.message()) + .await + .is_err() + ); + } + + #[test] + fn bootstrap_requires_matching_provider_revision_fence() { + let mut bootstrap = ConfigBootstrap { + sandbox_config: Some(SandboxConfigSnapshot { + provider_env_revision: 7, + ..Default::default() + }), + provider_environment: Some(ProviderEnvironmentSnapshot { + provider_env_revision: 8, + ..Default::default() + }), + }; + assert!(!bootstrap_revisions_match(&bootstrap)); + bootstrap + .provider_environment + .as_mut() + .unwrap() + .provider_env_revision = 7; + assert!(bootstrap_revisions_match(&bootstrap)); + } + + #[tokio::test] + async fn stalled_credentials_do_not_block_session_acceptance() { + use openshell_core::proto::{CredentialHandle, Provider}; + + let mut state = test_server_state().await; + Arc::get_mut(&mut state) + .unwrap() + .config + .config_delivery_mode = ConfigDeliveryMode::Push; + state + .store + .put_message(&Provider { + metadata: Some(ObjectMeta { + id: "provider".into(), + name: "provider".into(), + workspace: "default".into(), + ..Default::default() + }), + r#type: "github".into(), + credential_handles: HashMap::from([( + "GITHUB_TOKEN".into(), + CredentialHandle { + driver: "test-static".into(), + handle: "blocked".into(), + ..Default::default() + }, + )]), + ..Default::default() + }) + .await + .unwrap(); + state + .store + .put_message(&Sandbox { + metadata: Some(ObjectMeta { + id: "sandbox".into(), + name: "sandbox".into(), + workspace: "default".into(), + ..Default::default() + }), + spec: Some(SandboxSpec { + providers: vec!["provider".into()], + ..Default::default() + }), + ..Default::default() + }) + .await + .unwrap(); + let (resolve_hit, _release_resolve) = state.credentials.gate_next_resolve(); + tokio::time::timeout(Duration::from_secs(10), async { + let connect = connect_supervisor_stream( + &state, + "sandbox", + openshell_core::proto::SUPERVISOR_PROTOCOL_REVISION, + ); + let (response, hit) = tokio::join!(connect, resolve_hit); + hit.expect("bootstrap must reach the stalled credential driver"); + let mut harness = response.unwrap(); + let first = harness.inbound.message().await.unwrap().unwrap(); + let Some(gateway_message::Payload::SessionAccepted(accepted)) = first.payload else { + panic!("expected session acceptance"); + }; + assert!(accepted.bootstrap.is_none()); + assert!( + state + .supervisor_sessions + .is_current_session("sandbox", &accepted.session_id) + ); + // Relay control remains usable while credential resolution is stalled. + let (_, relay) = state + .supervisor_sessions + .open_relay("sandbox", Duration::from_secs(1)) + .await + .unwrap(); + let message = harness.inbound.message().await.unwrap().unwrap(); + assert!(matches!( + message.payload, + Some(gateway_message::Payload::RelayOpen(_)) + )); + drop(relay); + }) + .await + .expect("optional bootstrap must not consume the relay reconnect budget"); + } +} diff --git a/crates/openshell-server/src/config_file.rs b/crates/openshell-server/src/config_file.rs index e442607d9d..cd9700c5ef 100644 --- a/crates/openshell-server/src/config_file.rs +++ b/crates/openshell-server/src/config_file.rs @@ -123,6 +123,9 @@ pub struct GatewayFileSection { /// Security posture when a sandbox rejects a candidate policy generation. #[serde(default)] pub policy_validation_failure_mode: Option, + /// Supervisor configuration delivery; omitted uses the release default. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub config_delivery_mode: Option, // ── Service routing ────────────────────────────────────────────────── /// Subject Alternative Names configured on the gateway server certificate. @@ -1030,6 +1033,29 @@ policy_validation_failure_mode = "keep_old" assert!(error.to_string().contains("policy_validation_failure_mode")); } + #[test] + fn parses_delivery_mode_and_rejects_unknown_value() { + let tmp = write_tmp( + r#" +[openshell.gateway] +config_delivery_mode = "push" +"#, + ); + let file = load(tmp.path()).unwrap(); + assert_eq!( + file.openshell.gateway.config_delivery_mode, + Some(openshell_core::config::ConfigDeliveryMode::Push) + ); + + let tmp = write_tmp( + r#" +[openshell.gateway] +config_delivery_mode = "enabled" +"#, + ); + assert!(load(tmp.path()).is_err()); + } + #[test] fn parses_gateway_auth_config() { let toml = r" diff --git a/crates/openshell-server/src/credentials.rs b/crates/openshell-server/src/credentials.rs index 901a44f9f3..66677952b4 100644 --- a/crates/openshell-server/src/credentials.rs +++ b/crates/openshell-server/src/credentials.rs @@ -95,6 +95,16 @@ pub trait CredentialDriver: std::fmt::Debug + Send + Sync { #[cfg(test)] fn fail_next_delete(&self) {} + #[cfg(test)] + fn gate_next_resolve( + &self, + ) -> Option<( + tokio::sync::oneshot::Receiver<()>, + tokio::sync::oneshot::Sender<()>, + )> { + None + } + #[cfg(test)] fn gate_next_store( &self, @@ -291,6 +301,19 @@ impl CredentialRuntime { .expect("test credential driver supports store gating") } + #[cfg(test)] + pub(crate) fn gate_next_resolve( + &self, + ) -> ( + tokio::sync::oneshot::Receiver<()>, + tokio::sync::oneshot::Sender<()>, + ) { + self.drivers + .get(&self.registry.storage_owner_name()) + .and_then(|driver| driver.gate_next_resolve()) + .expect("test credential driver supports resolve gating") + } + pub async fn store_provider_credentials( &self, provider_name: &str, @@ -1848,6 +1871,13 @@ struct TestStaticCredentialDriver { fail_next_store: std::sync::atomic::AtomicBool, fail_next_delete: std::sync::atomic::AtomicBool, #[cfg(test)] + resolve_gate: std::sync::Mutex< + Option<( + tokio::sync::oneshot::Sender<()>, + tokio::sync::oneshot::Receiver<()>, + )>, + >, + #[cfg(test)] store_gate: std::sync::Mutex< Option<( tokio::sync::oneshot::Sender<()>, @@ -1866,6 +1896,8 @@ impl TestStaticCredentialDriver { fail_next_store: std::sync::atomic::AtomicBool::new(false), fail_next_delete: std::sync::atomic::AtomicBool::new(false), #[cfg(test)] + resolve_gate: std::sync::Mutex::new(None), + #[cfg(test)] store_gate: std::sync::Mutex::new(None), } } @@ -1943,6 +1975,17 @@ impl CredentialDriver for TestStaticCredentialDriver { requests: Vec, ) -> Result, Status> { let mut responses = Vec::with_capacity(requests.len()); + #[cfg(test)] + let gate = self + .resolve_gate + .lock() + .ok() + .and_then(|mut gate| gate.take()); + #[cfg(test)] + if let Some((hit, release)) = gate { + let _ = hit.send(()); + let _ = release.await; + } for request in requests { let handle = Self::handle_from_request(&request.request_id, request.handle)?; let value = self @@ -1973,6 +2016,19 @@ impl CredentialDriver for TestStaticCredentialDriver { .store(true, std::sync::atomic::Ordering::SeqCst); } + #[cfg(test)] + fn gate_next_resolve( + &self, + ) -> Option<( + tokio::sync::oneshot::Receiver<()>, + tokio::sync::oneshot::Sender<()>, + )> { + let (hit_tx, hit_rx) = tokio::sync::oneshot::channel(); + let (release_tx, release_rx) = tokio::sync::oneshot::channel(); + *self.resolve_gate.lock().ok()? = Some((hit_tx, release_rx)); + Some((hit_rx, release_tx)) + } + #[cfg(test)] fn fail_next_delete(&self) { self.fail_next_delete diff --git a/crates/openshell-server/src/grpc/mod.rs b/crates/openshell-server/src/grpc/mod.rs index 5ac58307a4..3794ac51d8 100644 --- a/crates/openshell-server/src/grpc/mod.rs +++ b/crates/openshell-server/src/grpc/mod.rs @@ -50,7 +50,8 @@ use openshell_core::proto::{ ListSandboxProvidersResponse, ListSandboxTemplatesRequest, ListSandboxTemplatesResponse, ListSandboxesRequest, ListSandboxesResponse, ListServicesRequest, ListServicesResponse, ListWorkspaceMembersRequest, ListWorkspaceMembersResponse, ListWorkspacesRequest, - ListWorkspacesResponse, MemoryResourceCapabilities, NegotiatedExtensionInfo, PeerRelayFrame, + ListWorkspacesResponse, MemoryResourceCapabilities, NegotiatedExtensionInfo, + PeerConfigUpdateHintRequest, PeerConfigUpdateHintResponse, PeerRelayFrame, ProviderProfileResponse, ProviderResponse, PushSandboxLogsRequest, PushSandboxLogsResponse, RefreshSandboxTokenRequest, RefreshSandboxTokenResponse, RejectDraftChunkRequest, RejectDraftChunkResponse, RelayFrame, RemoveWorkspaceMemberRequest, @@ -889,6 +890,13 @@ impl OpenShell for OpenShellService { ) -> Result, Status> { provider_readiness::handle_peer_get_sandbox_provider_status(&self.state, request).await } + + async fn peer_notify_config_update( + &self, + request: Request, + ) -> Result, Status> { + crate::config_delivery::handle_peer_config_update_hint(&self.state, request).await + } } fn public_extension_info(extension: &NegotiatedExtension) -> NegotiatedExtensionInfo { @@ -951,8 +959,76 @@ pub mod test_support { use crate::supervisor_session::SupervisorSessionRegistry; use crate::tracing_bus::TracingLogBus; use openshell_core::Config; + use openshell_core::proto::open_shell_client::OpenShellClient; + use openshell_core::proto::open_shell_server::OpenShellServer; + use openshell_core::proto::{ + GatewayMessage, SupervisorHello, SupervisorMessage, supervisor_message, + }; + use tokio::sync::mpsc; + use tokio_stream::wrappers::{ReceiverStream, TcpListenerStream}; use tonic::Request; + /// A live `ConnectSupervisor` stream against an in-process gateway. + pub struct SupervisorStreamHarness { + server: tokio::task::JoinHandle>, + /// Held so the supervisor side of the stream stays open. + _outbound: mpsc::Sender, + pub inbound: tonic::Streaming, + } + + impl Drop for SupervisorStreamHarness { + fn drop(&mut self) { + self.server.abort(); + } + } + + /// Serve `state` on loopback and open a supervisor stream whose hello + /// carries the given protocol revision. Returns the gRPC status when the + /// gateway rejects the stream before accepting it. + pub async fn connect_supervisor_stream( + state: &Arc, + sandbox_id: &str, + protocol_revision: u32, + ) -> Result { + let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); + let address = listener.local_addr().unwrap(); + let server = tokio::spawn( + tonic::transport::Server::builder() + .add_service(OpenShellServer::new(super::OpenShellService::new( + Arc::clone(state), + ))) + .serve_with_incoming(TcpListenerStream::new(listener)), + ); + let mut client = OpenShellClient::connect(format!("http://{address}")) + .await + .unwrap(); + let (outbound, rx) = mpsc::channel(4); + outbound + .send(SupervisorMessage { + payload: Some(supervisor_message::Payload::Hello(SupervisorHello { + sandbox_id: sandbox_id.into(), + instance_id: "instance".into(), + protocol_revision, + connection_epoch: 0, + supports_provider_readiness: false, + })), + }) + .await + .unwrap(); + let inbound = match client.connect_supervisor(ReceiverStream::new(rx)).await { + Ok(response) => response.into_inner(), + Err(status) => { + server.abort(); + return Err(status); + } + }; + Ok(SupervisorStreamHarness { + server, + _outbound: outbound, + inbound, + }) + } + /// Wrap a proto message in a `Request` with a dev principal injected. /// /// The dev principal matches the unauthenticated dev user: subject diff --git a/crates/openshell-server/src/grpc/policy.rs b/crates/openshell-server/src/grpc/policy.rs index 639e6c88ed..2356770d9e 100644 --- a/crates/openshell-server/src/grpc/policy.rs +++ b/crates/openshell-server/src/grpc/policy.rs @@ -38,7 +38,10 @@ use crate::storage_proto::StoredProviderCredentialRefreshStateV2 as StoredProvid #[cfg(test)] use crate::storage_proto::StoredProviderProfile; use openshell_core::net::{is_always_blocked_ip, is_internal_ip}; -use openshell_core::policy_identity::{canonical_rule_bytes, deterministic_policy_hash}; +use openshell_core::policy_identity::canonical_rule_bytes; +pub use openshell_core::policy_identity::deterministic_policy_hash; +#[cfg(test)] +use openshell_core::proto::StaticCredentialBinding; use openshell_core::proto::policy_merge_operation; use openshell_core::proto::setting_value; use openshell_core::proto::{ @@ -52,12 +55,13 @@ use openshell_core::proto::{ GetSandboxPolicyStatusRequest, GetSandboxPolicyStatusResponse, GetSandboxProviderEnvironmentRequest, GetSandboxProviderEnvironmentResponse, L7RuleTarget as ProtoL7RuleTarget, ListSandboxPoliciesRequest, ListSandboxPoliciesResponse, - PolicyChunk, PolicyMergeOperation, PolicySource, PolicyStatus, ProviderReadinessReason, + PolicyChunk, PolicyMergeOperation, PolicySource, PolicyStatus, ProviderEnvironmentSnapshot, + ProviderEnvironmentValue, ProviderEnvironmentValueClassification, ProviderReadinessReason, PushSandboxLogsRequest, PushSandboxLogsResponse, RejectDraftChunkRequest, RejectDraftChunkResponse, ReportPolicyStatusRequest, ReportPolicyStatusResponse, - SandboxLogLine, SandboxPolicyRevision, SettingScope, SettingValue, SubmitPolicyAnalysisRequest, - SubmitPolicyAnalysisResponse, UndoDraftChunkRequest, UndoDraftChunkResponse, - UpdateConfigRequest, UpdateConfigResponse, + SandboxConfigSnapshot, SandboxLogLine, SandboxPolicyRevision, SettingScope, SettingValue, + SubmitPolicyAnalysisRequest, SubmitPolicyAnalysisResponse, UndoDraftChunkRequest, + UndoDraftChunkResponse, UpdateConfigRequest, UpdateConfigResponse, }; use openshell_core::proto::{ L7DenyRule, L7Rule, NetworkBinary, NetworkEndpoint, NetworkPolicyRule, Provider, Sandbox, @@ -92,7 +96,7 @@ use sha2::{Digest, Sha256}; use std::collections::{BTreeMap, HashMap, HashSet}; use std::net::IpAddr; use std::sync::Arc; -use tonic::{Request, Response, Status}; +use tonic::{Code, Request, Response, Status}; use tracing::{debug, info, warn}; use super::validation::{ @@ -1845,6 +1849,11 @@ async fn auto_approve_chunk( return Err(status); } }; + crate::config_delivery::publish_sandbox_components( + state, + sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); let chunk_summary = summarize_draft_chunk_rule(&chunk)?; let now_ms = current_time_ms(); @@ -2669,7 +2678,7 @@ async fn resolve_sandbox_by_name_for_principal( }; crate::auth::guard::ensure_sandbox_scope(principal, sandbox.object_id()).map_err( |status| { - if status.code() == tonic::Code::PermissionDenied { + if status.code() == Code::PermissionDenied { Status::permission_denied("sandbox not found or not owned by caller") } else { status @@ -2710,7 +2719,7 @@ pub(super) async fn handle_get_sandbox_config( if matches!(principal, Principal::Sandbox(_)) && matches!( error.code(), - tonic::Code::FailedPrecondition | tonic::Code::InvalidArgument + Code::FailedPrecondition | Code::InvalidArgument ) => { // A malformed stored candidate must not prevent a supervisor @@ -2767,6 +2776,18 @@ pub(super) async fn load_sandbox_config( state: &Arc, sandbox: &Sandbox, ) -> Result { + Ok(sandbox_config_response( + build_sandbox_config_snapshot(state, sandbox).await?, + )) +} + +/// Build the complete effective configuration for one persisted sandbox. +/// +/// This is a read-only projection shared by polling and stream delivery. +pub async fn build_sandbox_config_snapshot( + state: &Arc, + sandbox: &Sandbox, +) -> Result { let sandbox_id = sandbox.object_id().to_string(); let workspace = sandbox.object_workspace().to_string(); let sandbox_provider_names = sandbox @@ -2792,87 +2813,49 @@ pub(super) async fn load_sandbox_config( .await .map_err(|e| Status::internal(format!("fetch policy history failed: {e}")))?; - let (mut policy, version, mut policy_hash, policy_source) = if let Some(global_policy) = - global_policy - { - let version = latest - .as_ref() - .map(|record| u32::try_from(record.version).unwrap_or(0)) - .filter(|version| *version > 0) - .unwrap_or(1); - let hash = deterministic_policy_hash(&global_policy); - (Some(global_policy), version, hash, PolicySource::Global) - } else if let Some(record) = latest { - let (policy, hash) = canonical_policy_record_identity(&record)?; - debug!( - sandbox_id = %sandbox_id, - version = record.version, - "GetSandboxConfig served from policy history" - ); - ( - Some(policy), - u32::try_from(record.version).unwrap_or(0), - hash, - PolicySource::Sandbox, - ) - } else { - // Lazy backfill: no policy history exists yet. - let spec = sandbox - .spec - .as_ref() - .ok_or_else(|| Status::internal("sandbox has no spec"))?; - - match spec.policy.clone() { - None => { - debug!( - sandbox_id = %sandbox_id, - "GetSandboxConfig: no policy configured, returning empty response" - ); - (None, 0, String::new(), PolicySource::Sandbox) - } - Some(spec_policy) => { - // Stored specs may predate the current schema. Validate before - // creating policy history so malformed state is never copied or - // marked loaded, and hash the canonical representation. - let spec_policy = validate_and_canonicalize_stored_policy( - spec_policy, - STORED_POLICY_SOURCE_SPEC, - )?; - let hash = deterministic_policy_hash(&spec_policy); - let payload = spec_policy.encode_to_vec(); - let policy_id = uuid::Uuid::new_v4().to_string(); - - if let Err(e) = state - .store - .put_policy_revision(&policy_id, &sandbox_id, &workspace, 1, &payload, &hash) - .await - { - warn!( - sandbox_id = %sandbox_id, - error = %e, - "Failed to backfill policy version 1" - ); - } else if let Err(e) = state - .store - .update_policy_status(&sandbox_id, 1, "loaded", None, None) - .await - { - warn!( - sandbox_id = %sandbox_id, - error = %e, - "Failed to mark backfilled policy as loaded" - ); + let (mut policy, version, mut policy_hash, policy_source) = + if let Some(global_policy) = global_policy { + let version = latest + .as_ref() + .map(|record| u32::try_from(record.version).unwrap_or(0)) + .filter(|version| *version > 0) + .unwrap_or(1); + let hash = deterministic_policy_hash(&global_policy); + (Some(global_policy), version, hash, PolicySource::Global) + } else if let Some(record) = latest { + let (policy, hash) = canonical_policy_record_identity(&record)?; + debug!( + sandbox_id = %sandbox_id, + version = record.version, + "GetSandboxConfig served from policy history" + ); + ( + Some(policy), + u32::try_from(record.version).unwrap_or(0), + hash, + PolicySource::Sandbox, + ) + } else { + // Older sandboxes may have policy only in the sandbox spec. Reading a + // snapshot must not create policy history, so project that baseline as + // version 1 until the startup repair persists it. + let spec = sandbox + .spec + .as_ref() + .ok_or_else(|| Status::internal("sandbox has no spec"))?; + + match spec.policy.clone() { + None => (None, 0, String::new(), PolicySource::Sandbox), + Some(spec_policy) => { + let spec_policy = validate_and_canonicalize_stored_policy( + spec_policy, + STORED_POLICY_SOURCE_SPEC, + )?; + let hash = deterministic_policy_hash(&spec_policy); + (Some(spec_policy), 1, hash, PolicySource::Sandbox) } - - info!( - sandbox_id = %sandbox_id, - "GetSandboxConfig served from spec (backfilled version 1)" - ); - - (Some(spec_policy), 1, hash, PolicySource::Sandbox) } - } - }; + }; let global_settings = load_global_settings(state.store.as_ref()).await?; let sandbox_settings = @@ -2978,7 +2961,7 @@ pub(super) async fn load_sandbox_config( &policy_credential_bindings, )?; - Ok(GetSandboxConfigResponse { + Ok(SandboxConfigSnapshot { configuration_instance_id: sandbox .status .as_ref() @@ -3010,6 +2993,140 @@ pub(super) async fn load_sandbox_config( }) } +fn sandbox_config_response(snapshot: SandboxConfigSnapshot) -> GetSandboxConfigResponse { + GetSandboxConfigResponse { + policy: snapshot.policy, + version: snapshot.version, + policy_hash: snapshot.policy_hash, + settings: snapshot.settings, + config_revision: snapshot.config_revision, + policy_source: snapshot.policy_source, + global_policy_version: snapshot.global_policy_version, + provider_env_revision: snapshot.provider_env_revision, + supervisor_middleware_services: snapshot.supervisor_middleware_services, + workspace: snapshot.workspace, + policy_validation_failure_mode: snapshot.policy_validation_failure_mode, + extension_authentication_enabled: snapshot.extension_authentication_enabled, + provider_attachment_epoch: snapshot.provider_attachment_epoch, + configuration_admitted: snapshot.configuration_admitted, + configuration_error: snapshot.configuration_error, + configuration_instance_id: snapshot.configuration_instance_id, + } +} + +#[derive(Clone, Copy)] +pub enum InitialPolicyHistoryStatus { + Pending, + Loaded, +} + +impl InitialPolicyHistoryStatus { + fn as_str(self) -> &'static str { + match self { + Self::Pending => "pending", + Self::Loaded => "loaded", + } + } +} + +/// Insert the version-one policy baseline if this sandbox still has no policy +/// history. This never modifies an existing revision or apply result. +/// +/// Returns `true` when a baseline was written. Stored policies that fail the +/// current validation rules are rejected with `FailedPrecondition`. +pub async fn initialize_policy_history( + store: &Store, + sandbox: &Sandbox, + status: InitialPolicyHistoryStatus, +) -> Result { + let Some(policy) = sandbox.spec.as_ref().and_then(|spec| spec.policy.as_ref()) else { + return Ok(false); + }; + if store + .get_latest_policy(sandbox.object_id()) + .await + .map_err(|error| Status::internal(format!("read policy history failed: {error}")))? + .is_some() + { + return Ok(false); + } + let policy = + validate_and_canonicalize_stored_policy(policy.clone(), STORED_POLICY_SOURCE_SPEC)?; + store + .put_initial_policy_revision( + &PolicyRecord { + id: uuid::Uuid::new_v4().to_string(), + sandbox_id: sandbox.object_id().to_string(), + version: 1, + policy_payload: policy.encode_to_vec(), + policy_hash: deterministic_policy_hash(&policy), + status: status.as_str().to_string(), + load_error: None, + created_at_ms: current_time_ms(), + loaded_at_ms: None, + provenance: HashMap::new(), + }, + sandbox.object_workspace(), + ) + .await + .map_err(|error| Status::internal(format!("initialize policy history failed: {error}")))?; + Ok(true) +} + +/// Create policy-history baselines for sandboxes written by older gateways. +/// +/// Snapshot reads stay pure once this startup repair has completed. A stored +/// policy that no longer passes validation is skipped rather than blocking +/// gateway startup; that sandbox keeps the pre-repair behavior where its own +/// configuration reads report the validation failure. Store errors remain +/// fatal. +pub async fn backfill_legacy_policy_history(state: &Arc) -> Result<(), Status> { + const PAGE_SIZE: u32 = 1000; + let mut offset = 0; + let mut repaired = 0_usize; + let mut skipped = 0_usize; + loop { + let sandboxes = state + .store + .list_all_messages::(PAGE_SIZE, offset) + .await + .map_err(|error| { + Status::internal(format!("list sandboxes for policy repair failed: {error}")) + })?; + let count = u32::try_from(sandboxes.len()).unwrap_or(PAGE_SIZE); + for sandbox in sandboxes { + match initialize_policy_history( + state.store.as_ref(), + &sandbox, + InitialPolicyHistoryStatus::Loaded, + ) + .await + { + Ok(true) => repaired += 1, + Ok(false) => {} + Err(status) if status.code() == Code::FailedPrecondition => { + skipped += 1; + warn!( + sandbox_id = %sandbox.object_id(), + workspace = %sandbox.object_workspace(), + error = %status.message(), + "skipping policy history repair for invalid stored policy" + ); + } + Err(status) => return Err(status), + } + } + if count < PAGE_SIZE { + break; + } + offset = offset.saturating_add(count); + } + if repaired > 0 || skipped > 0 { + info!(repaired, skipped, "legacy policy history repair complete"); + } + Ok(()) +} + #[cfg(test)] async fn compute_provider_env_revision( store: &Store, @@ -3529,6 +3646,18 @@ pub(super) async fn load_sandbox_provider_environment( sandbox: &Sandbox, supports_static_credential_bindings: bool, ) -> Result { + Ok(provider_environment_response( + build_provider_environment_snapshot(state, sandbox, supports_static_credential_bindings) + .await?, + )) +} + +/// Build the complete provider environment for one persisted sandbox. +pub async fn build_provider_environment_snapshot( + state: &Arc, + sandbox: &Sandbox, + supports_static_credential_bindings: bool, +) -> Result { let sandbox_id = sandbox.object_id().to_string(); let workspace = sandbox.object_workspace().to_string(); @@ -3627,37 +3756,98 @@ pub(super) async fn load_sandbox_provider_environment( "GetSandboxProviderEnvironment request completed successfully" ); - let non_secret_environment_keys = provider_environment + let mut keys = provider_environment .environment .keys() - .filter(|key| !provider_environment.static_credential_keys.contains(*key)) .cloned() - .collect(); + .collect::>(); + keys.sort(); + let mut values = Vec::with_capacity(keys.len()); + for name in keys { + let value = provider_environment + .environment + .remove(&name) + .expect("provider environment key came from the same map"); + let is_static_credential = provider_environment.static_credential_keys.contains(&name); + let static_credential_binding = provider_environment + .static_credential_bindings + .remove(&name); + if is_static_credential && static_credential_binding.is_none() { + return Err(Status::failed_precondition(format!( + "static provider credential '{name}' has no endpoint binding" + ))); + } + values.push(ProviderEnvironmentValue { + name: name.clone(), + value, + expiration_time: provider_environment + .credential_expiration_times + .remove(&name) + .and_then(|expires_at_ms| { + openshell_core::time::optional_timestamp_from_legacy_millis(expires_at_ms) + .ok() + .flatten() + }), + classification: if is_static_credential { + ProviderEnvironmentValueClassification::StaticCredential.into() + } else { + ProviderEnvironmentValueClassification::NonSecret.into() + }, + static_credential_binding, + }); + } - let credential_expiration_times = provider_environment - .credential_expiration_times - .into_iter() - .filter_map(|(key, value)| { - openshell_core::time::optional_timestamp_from_legacy_millis(value) - .ok() - .flatten() - .map(|timestamp| (key, timestamp)) - }) - .collect(); - Ok(GetSandboxProviderEnvironmentResponse { - environment: provider_environment.environment, - files: provider_environment.files, + Ok(ProviderEnvironmentSnapshot { provider_env_revision, - credential_expiration_times, + values, + files: provider_environment.files, dynamic_credentials: provider_environment.dynamic_credentials, - static_credential_bindings: provider_environment.static_credential_bindings, - non_secret_environment_keys, provider_attachment_epoch: spec.provider_attachment_epoch.clone(), policy_hash: deterministic_policy_hash(&effective_policy), readiness_reason: readiness_reason.into(), }) } +fn provider_environment_response( + snapshot: ProviderEnvironmentSnapshot, +) -> GetSandboxProviderEnvironmentResponse { + let mut environment = HashMap::with_capacity(snapshot.values.len()); + let mut credential_expiration_times = HashMap::new(); + let mut static_credential_bindings = HashMap::new(); + let mut non_secret_environment_keys = Vec::new(); + for value in snapshot.values { + environment.insert(value.name.clone(), value.value); + if let Some(expiration_time) = value.expiration_time { + credential_expiration_times.insert(value.name.clone(), expiration_time); + } + match ProviderEnvironmentValueClassification::try_from(value.classification) + .unwrap_or_default() + { + ProviderEnvironmentValueClassification::NonSecret => { + non_secret_environment_keys.push(value.name); + } + ProviderEnvironmentValueClassification::StaticCredential => { + if let Some(binding) = value.static_credential_binding { + static_credential_bindings.insert(value.name, binding); + } + } + ProviderEnvironmentValueClassification::Unspecified => {} + } + } + GetSandboxProviderEnvironmentResponse { + environment, + files: snapshot.files, + provider_env_revision: snapshot.provider_env_revision, + credential_expiration_times, + dynamic_credentials: snapshot.dynamic_credentials, + static_credential_bindings, + non_secret_environment_keys, + provider_attachment_epoch: snapshot.provider_attachment_epoch, + policy_hash: snapshot.policy_hash, + readiness_reason: snapshot.readiness_reason, + } +} + // --------------------------------------------------------------------------- // Update config handler (policy + settings mutations) // --------------------------------------------------------------------------- @@ -3811,6 +4001,10 @@ async fn handle_update_config_inner( if changed { global_settings.revision = global_settings.revision.wrapping_add(1); save_global_settings(state.store.as_ref(), &global_settings).await?; + crate::config_delivery::publish_all_connected( + state, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); } return Ok(update_config_response( u32::try_from(current.version).unwrap_or(0), @@ -3867,6 +4061,10 @@ async fn handle_update_config_inner( if changed { global_settings.revision = global_settings.revision.wrapping_add(1); save_global_settings(state.store.as_ref(), &global_settings).await?; + crate::config_delivery::publish_all_connected( + state, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); } return Ok(update_config_response( @@ -3913,6 +4111,10 @@ async fn handle_update_config_inner( global_settings.revision = global_settings.revision.wrapping_add(1); save_global_settings(state.store.as_ref(), &global_settings).await?; + crate::config_delivery::publish_all_connected( + state, + crate::config_delivery::ConfigComponents::SANDBOX_CONFIG, + ); if req.delete_setting && key == POLICY_SETTING_KEY @@ -3977,6 +4179,11 @@ async fn handle_update_config_inner( &sandbox_settings, ) .await?; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_CONFIG, + ); } response_annotations = persist_update_config_annotations( @@ -4021,6 +4228,11 @@ async fn handle_update_config_inner( &sandbox_settings, ) .await?; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_CONFIG, + ); } response_annotations = persist_update_config_annotations( @@ -4082,6 +4294,11 @@ async fn handle_update_config_inner( Some(&atomic_context), ) .await?; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); response_annotations = if let Some(updated_sandbox) = updated_sandbox { sandbox_metadata_annotations(&updated_sandbox) } else { @@ -4301,6 +4518,11 @@ async fn handle_update_config_inner( })? }; response_annotations = committed_annotations; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); state.sandbox_watch_bus.notify(&sandbox_id); // The committed revision changed what pending proposals were evaluated // against. Schedule the refresh here: the matching-revision check below @@ -4351,6 +4573,12 @@ async fn handle_update_config_inner( .await .map_err(|e| Status::internal(format!("persist policy revision failed: {e}")))?; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); + let _ = state .store .supersede_older_policies(&sandbox_id, next_version) @@ -5586,6 +5814,11 @@ async fn handle_approve_draft_chunk_inner( return Err(status); } }; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); let chunk_summary = summarize_draft_chunk_rule(&chunk)?; let now_ms = current_time_ms(); @@ -5702,6 +5935,11 @@ async fn handle_reject_draft_chunk_inner( require_no_global_policy(state).await?; let (version, hash) = remove_chunk_from_policy(state, &sandbox_id, &workspace, &chunk).await?; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); emit_gateway_policy_audit_log( &sandbox_id, sandbox.object_name(), @@ -5856,7 +6094,7 @@ async fn handle_approve_all_draft_chunks_inner( .await { Ok(evaluation) => evaluation, - Err(status) if status.code() == tonic::Code::FailedPrecondition => { + Err(status) if status.code() == Code::FailedPrecondition => { info!( sandbox_id = %sandbox_id, chunk_id = %chunk.id, @@ -5987,6 +6225,14 @@ async fn handle_approve_all_draft_chunks_inner( } }; + if !accepted.is_empty() { + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); + } + for (chunk, _, chunk_summary) in &accepted { let now_ms = current_time_ms(); clear_pending_application_error(state, &chunk.id).await; @@ -6175,6 +6421,11 @@ async fn handle_undo_draft_chunk_inner( ); let (version, hash) = remove_chunk_from_policy(state, &sandbox_id, &workspace, &chunk).await?; + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); // Clear any prior rejection_reason on the way back to "pending" so an // agent reading the chunk via policy.local cannot see a stale guidance @@ -7689,7 +7940,6 @@ mod tests { use std::collections::HashMap; use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; - use tonic::Code; /// Wrap a request with a user `Principal` so handler scope guards treat /// the test caller as a CLI user. Most handler tests exercise @@ -8489,7 +8739,7 @@ mod tests { } #[tokio::test] - async fn get_sandbox_config_backfills_canonical_spec_policy_bytes_and_hash() { + async fn startup_repair_backfills_canonical_spec_policy_bytes_and_hash() { let state = test_server_state().await; let sandbox_id = "stored-canonical-backfill"; let raw = mcp_policy_with_versions(&["2025-11-25", "2025-03-26", "2025-06-18"]); @@ -8525,6 +8775,15 @@ mod tests { assert_eq!(response.policy_hash, canonical_hash); assert_eq!(response.version, 1); + assert!( + state + .store + .get_latest_policy(sandbox_id) + .await + .unwrap() + .is_none() + ); + backfill_legacy_policy_history(&state).await.unwrap(); let persisted = state .store .get_latest_policy(sandbox_id) @@ -8537,7 +8796,7 @@ mod tests { } #[tokio::test] - async fn get_sandbox_config_backfills_defaulted_mcp_policy_as_canonical_bytes_and_hash() { + async fn startup_repair_backfills_defaulted_mcp_policy_as_canonical_bytes_and_hash() { let state = test_server_state().await; let canonical = validate_and_canonicalize_policy(mcp_policy_with_versions(&["2025-11-25"])) .expect("explicit default MCP policy must canonicalize"); @@ -8584,6 +8843,15 @@ mod tests { "{case}" ); + assert!( + state + .store + .get_latest_policy(&sandbox_id) + .await + .unwrap() + .is_none() + ); + backfill_legacy_policy_history(&state).await.unwrap(); let persisted = state .store .get_latest_policy(&sandbox_id) @@ -8876,6 +9144,10 @@ mod tests { .await .expect("store sandbox with invalid legacy spec"); + backfill_legacy_policy_history(&state) + .await + .expect("global override must allow startup with an invalid dormant spec"); + let response = handle_get_sandbox_config( &state, with_sandbox( @@ -12412,6 +12684,133 @@ mod tests { ); } + #[tokio::test] + async fn rejected_policy_update_does_not_publish_configuration() { + let state = test_server_state().await; + let mut sandbox = test_sandbox( + "sb-rejected-policy", + "rejected-policy", + ProtoSandboxPolicy::default(), + Vec::new(), + ); + sandbox.spec.as_mut().unwrap().policy = None; + state.store.put_message(&sandbox).await.unwrap(); + + let (tx, mut rx) = tokio::sync::mpsc::channel(1); + let (shutdown_tx, _shutdown_rx) = tokio::sync::oneshot::channel(); + state.supervisor_sessions.register( + "sb-rejected-policy".to_string(), + "session-1".to_string(), + tx, + shutdown_tx, + ); + + let error = handle_update_config( + &state, + with_user(Request::new(UpdateConfigRequest { + sandbox: "rejected-policy".to_string(), + workspace_scope: Some(openshell_core::proto::workspace_selector("default")), + policy: Some(test_policy_with_rule("rejected", "api.example.com")), + expected_resource_version: u64::MAX, + ..Default::default() + })), + ) + .await + .expect_err("stale resource version must reject the update"); + + assert_eq!(error.code(), Code::Aborted); + assert!(rx.try_recv().is_err()); + assert!( + state + .store + .get_latest_policy("sb-rejected-policy") + .await + .unwrap() + .is_none() + ); + } + + #[tokio::test] + async fn committed_policy_update_publishes_complete_snapshot() { + let mut state = test_server_state().await; + Arc::get_mut(&mut state) + .unwrap() + .config + .config_delivery_mode = openshell_core::config::ConfigDeliveryMode::Push; + let mut sandbox = test_sandbox( + "sb-published-policy", + "published-policy", + ProtoSandboxPolicy::default(), + Vec::new(), + ); + sandbox.spec.as_mut().unwrap().policy = None; + state.store.put_message(&sandbox).await.unwrap(); + + let (tx, mut rx) = tokio::sync::mpsc::channel(4); + let (shutdown_tx, _shutdown_rx) = tokio::sync::oneshot::channel(); + state.supervisor_sessions.register( + "sb-published-policy".to_string(), + "session-1".to_string(), + tx, + shutdown_tx, + ); + let owner_index = crate::supervisor_owner::SupervisorOwnerIndex::new( + Arc::clone(&state.store), + crate::supervisor_owner::OWNER_TTL, + ); + owner_index + .publish( + "sb-published-policy", + "session-1", + "test-supervisor", + 1, + &state.replica_id, + "local://test", + ) + .await + .unwrap(); + + handle_update_config( + &state, + with_user(Request::new(UpdateConfigRequest { + sandbox: "published-policy".to_string(), + workspace_scope: Some(openshell_core::proto::workspace_selector("default")), + policy: Some(test_policy_with_rule("published", "api.example.com")), + ..Default::default() + })), + ) + .await + .unwrap(); + + let persisted = state + .store + .get_latest_policy("sb-published-policy") + .await + .unwrap() + .expect("committed policy"); + let snapshot = tokio::time::timeout(std::time::Duration::from_secs(2), async { + loop { + let message = rx.recv().await.expect("configuration channel closed"); + let Some(openshell_core::proto::gateway_message::Payload::ConfigUpdate(update)) = + message.payload + else { + panic!("expected ConfigUpdate"); + }; + if let Some(openshell_core::proto::config_update::Component::SandboxConfig( + snapshot, + )) = update.component + { + break snapshot; + } + } + }) + .await + .expect("configuration publication timed out"); + assert_eq!(snapshot.version, u32::try_from(persisted.version).unwrap()); + assert_eq!(snapshot.policy_hash, persisted.policy_hash); + assert!(snapshot.policy.is_some()); + } + #[tokio::test] async fn update_config_accepts_sigv4_covered_by_endpointful_aws_profile() { let state = test_server_state().await; @@ -12743,23 +13142,147 @@ mod tests { .contains_key("_provider_work_github") ); - let persisted = state + assert!( + state + .store + .get_latest_policy("sb-jit") + .await + .unwrap() + .is_none(), + "snapshot reads must not create policy history" + ); + } + + #[tokio::test] + async fn legacy_policy_history_repair_skips_invalid_stored_policy() { + use openshell_core::proto::LandlockPolicy; + + let state = test_server_state().await; + let valid_policy = test_policy_with_rule("valid", "valid.example.com"); + state + .store + .put_message(&test_sandbox( + "sb-valid-legacy", + "valid-legacy", + valid_policy.clone(), + Vec::new(), + )) + .await + .unwrap(); + let mut invalid_policy = test_policy_with_rule("invalid", "invalid.example.com"); + invalid_policy.landlock = Some(LandlockPolicy { + compatibility: "best-effort".to_string(), + }); + state + .store + .put_message(&test_sandbox( + "sb-invalid-legacy", + "invalid-legacy", + invalid_policy, + Vec::new(), + )) + .await + .unwrap(); + + backfill_legacy_policy_history(&state) + .await + .expect("one invalid stored policy must not block startup repair"); + + let repaired = state .store - .get_latest_policy("sb-jit") + .get_latest_policy("sb-valid-legacy") .await .unwrap() - .expect("sandbox policy should be lazily backfilled"); - let persisted_policy = ProtoSandboxPolicy::decode(persisted.policy_payload.as_slice()) - .expect("persisted sandbox policy should decode"); - assert!( - persisted_policy - .network_policies - .contains_key("sandbox_only") + .expect("valid legacy sandbox gets a baseline"); + assert_eq!(repaired.version, 1); + assert_eq!(repaired.status, "loaded"); + assert_eq!( + repaired.policy_hash, + deterministic_policy_hash(&valid_policy) ); assert!( - !persisted_policy - .network_policies - .contains_key("_provider_work_github") + state + .store + .get_latest_policy("sb-invalid-legacy") + .await + .unwrap() + .is_none(), + "invalid stored policy must not be persisted as history" + ); + + let rejected = handle_get_sandbox_config( + &state, + with_sandbox( + Request::new(GetSandboxConfigRequest { + name: "invalid-legacy".to_string(), + workspace_scope: Some(openshell_core::proto::workspace_selector("default")), + }), + "sb-invalid-legacy", + ), + ) + .await + .expect("invalid stored policy returns a repairable admission snapshot") + .into_inner(); + assert!(!rejected.configuration_admitted); + assert!(rejected.policy.is_none()); + assert_eq!(rejected.workspace, "default"); + assert_eq!( + rejected.configuration_error, + "Stored policy structure or safety validation failed; submit a complete valid replacement policy" + ); + } + + #[tokio::test] + async fn legacy_policy_history_repair_is_idempotent() { + let state = test_server_state().await; + let policy = test_policy_with_rule("legacy", "legacy.example.com"); + state + .store + .put_message(&test_sandbox( + "sb-legacy-policy", + "legacy-policy", + policy.clone(), + Vec::new(), + )) + .await + .unwrap(); + + backfill_legacy_policy_history(&state).await.unwrap(); + let initial = state + .store + .get_latest_policy("sb-legacy-policy") + .await + .unwrap() + .expect("legacy policy baseline"); + assert_eq!(initial.status, "loaded"); + state + .store + .update_policy_status("sb-legacy-policy", 1, "failed", Some("apply failed"), None) + .await + .unwrap(); + + backfill_legacy_policy_history(&state).await.unwrap(); + let repaired_again = state + .store + .get_latest_policy("sb-legacy-policy") + .await + .unwrap() + .expect("legacy policy baseline"); + assert_eq!(repaired_again.version, 1); + assert_eq!( + repaired_again.policy_hash, + deterministic_policy_hash(&policy) + ); + assert_eq!(repaired_again.status, "failed"); + assert_eq!(repaired_again.load_error.as_deref(), Some("apply failed")); + assert_eq!( + state + .store + .list_policies("sb-legacy-policy", 10, 0) + .await + .unwrap() + .len(), + 1 ); } @@ -12888,24 +13411,14 @@ mod tests { assert_eq!(persisted_provider.r#type, provider.r#type); assert_eq!(persisted_provider.credentials, provider.credentials); - let persisted_policy = state - .store - .get_latest_policy("sb-custom-policy-update") - .await - .unwrap() - .expect("sandbox policy should be lazily backfilled"); - let persisted_policy = - ProtoSandboxPolicy::decode(persisted_policy.policy_payload.as_slice()) - .expect("persisted sandbox policy should decode"); assert!( - persisted_policy - .network_policies - .contains_key("sandbox_only") - ); - assert!( - !persisted_policy - .network_policies - .contains_key("_provider_work_custom") + state + .store + .get_latest_policy("sb-custom-policy-update") + .await + .unwrap() + .is_none(), + "config and profile reads must not create policy history" ); } @@ -23489,4 +24002,38 @@ mod tests { response.unwrap_err() ); } + + #[test] + fn provider_stream_values_expand_to_legacy_polling_response() { + let response = provider_environment_response(ProviderEnvironmentSnapshot { + provider_env_revision: 9, + values: vec![ + ProviderEnvironmentValue { + name: "REGION".into(), + value: "west".into(), + classification: ProviderEnvironmentValueClassification::NonSecret.into(), + ..Default::default() + }, + ProviderEnvironmentValue { + name: "TOKEN".into(), + value: "secret".into(), + expiration_time: openshell_core::time::timestamp_from_millis(123).ok(), + classification: ProviderEnvironmentValueClassification::StaticCredential.into(), + static_credential_binding: Some(StaticCredentialBinding::default()), + }, + ], + dynamic_credentials: HashMap::new(), + ..Default::default() + }); + + assert_eq!(response.provider_env_revision, 9); + assert_eq!(response.environment["REGION"], "west"); + assert_eq!(response.environment["TOKEN"], "secret"); + assert_eq!( + response.credential_expiration_times["TOKEN"], + openshell_core::time::timestamp_from_millis(123).unwrap() + ); + assert_eq!(response.non_secret_environment_keys, ["REGION"]); + assert!(response.static_credential_bindings.contains_key("TOKEN")); + } } diff --git a/crates/openshell-server/src/grpc/provider.rs b/crates/openshell-server/src/grpc/provider.rs index cc2395fe7d..41437384d1 100644 --- a/crates/openshell-server/src/grpc/provider.rs +++ b/crates/openshell-server/src/grpc/provider.rs @@ -2558,6 +2558,21 @@ async fn authorize_and_resolve_profile_workspace( } } +fn publish_provider_change(state: &Arc, workspace: &str) { + if workspace.is_empty() { + crate::config_delivery::publish_all_connected( + state, + crate::config_delivery::ConfigComponents::ALL, + ); + } else { + crate::config_delivery::publish_workspace_components( + state, + workspace, + crate::config_delivery::ConfigComponents::ALL, + ); + } +} + fn selected_profile_workspace( workspace_scope: Option<&openshell_core::proto::WorkspaceSelector>, ) -> Result<&str, Status> { @@ -2627,6 +2642,7 @@ pub(super) async fn handle_create_provider( LifecycleOperation::Create, TelemetryOutcome::Success, ); + publish_provider_change(state, &workspace); Ok(Response::new(ProviderResponse { provider: Some(provider), ..Default::default() @@ -2896,6 +2912,7 @@ pub(super) async fn handle_import_provider_profiles( stored.profile.unwrap_or_default(), resource_version, )); + publish_provider_change(state, &workspace); } Ok(Response::new(ImportProviderProfilesResponse { @@ -3031,6 +3048,7 @@ pub(super) async fn handle_update_provider_profiles( replay_facts.resource(&stored)?; let resource_version = stored_profile_resource_version(&stored); let profile = profile_response_payload(stored.profile.unwrap_or_default(), resource_version); + publish_provider_change(state, &workspace); Ok(Response::new(UpdateProviderProfilesResponse { diagnostics: Vec::new(), @@ -3125,6 +3143,7 @@ pub(super) async fn handle_delete_provider_profile( .delete(StoredProviderProfile::object_type(), existing.object_id()) .await .map_err(|e| Status::internal(format!("delete provider profile failed: {e}")))?; + publish_provider_change(state, &workspace); Ok(Response::new(DeleteProviderProfileResponse { outcome: openshell_core::proto::DeletionOutcome::Completed.into(), @@ -3977,6 +3996,7 @@ pub(super) async fn handle_update_provider( LifecycleOperation::Update, TelemetryOutcome::Success, ); + publish_provider_change(state, &workspace); Ok(Response::new(ProviderResponse { provider: Some(provider), target_receipts, @@ -4937,8 +4957,17 @@ pub(super) async fn handle_configure_provider_refresh( profile_workspace: String::new(), credential_handles: HashMap::new(), }; - update_provider_record_with_catalog(state.store.as_ref(), &catalog, &workspace, updated) - .await?; + let result = update_provider_record_with_catalog( + state.store.as_ref(), + &catalog, + &workspace, + updated, + ) + .await; + publish_provider_change(state, &workspace); + result?; + } else { + publish_provider_change(state, &workspace); } replay_facts.refresh(&state_record)?; @@ -4984,6 +5013,7 @@ pub(super) async fn handle_rotate_provider_credential( credential_key, ) .await?; + publish_provider_change(state, &workspace); replay_facts.refresh(&refresh_state)?; Ok(Response::new(RotateProviderCredentialResponse { @@ -5072,7 +5102,6 @@ pub(super) async fn handle_delete_provider_refresh( refresh_state.clone(), ) .await?; - // A refresh co-manages the expiry of its primary credential and every pinned // additional output. Clear each expiry this refresh still owns, leaving // independently updated ones in place. The equality check and removal run @@ -5094,8 +5123,10 @@ pub(super) async fn handle_delete_provider_refresh( Status::internal(format!( "clear refresh-owned credential expiries failed: {e}" )) - })?; + }) + .map(|_| ())?; } + publish_provider_change(state, &workspace); Ok(Response::new(DeleteProviderRefreshResponse { outcome: openshell_core::proto::DeletionOutcome::Completed.into(), @@ -5136,6 +5167,9 @@ pub(super) async fn handle_delete_provider( LifecycleOperation::Delete, outcome, ); + if deleted { + publish_provider_change(state, &workspace); + } Ok(Response::new(DeleteProviderResponse { outcome: super::deletion_outcome(deleted, req.allow_missing, "provider")?, })) diff --git a/crates/openshell-server/src/grpc/provider_readiness_tests.rs b/crates/openshell-server/src/grpc/provider_readiness_tests.rs index d83bb80ef4..44fcb63191 100644 --- a/crates/openshell-server/src/grpc/provider_readiness_tests.rs +++ b/crates/openshell-server/src/grpc/provider_readiness_tests.rs @@ -7,6 +7,7 @@ use crate::config_update_operation::CONFIG_UPDATE_OPERATION_OBJECT_TYPE; use crate::grpc::test_support::{authed_request, test_server_state}; use crate::persistence::WriteCondition; use crate::storage_proto::StoredConfigUpdateOperation; +use openshell_core::proto::SUPERVISOR_PROTOCOL_REVISION; use openshell_core::proto::SandboxSpec; use openshell_core::proto::datamodel::v1::ObjectMeta; use prost::Message; @@ -70,6 +71,7 @@ fn hello() -> SupervisorHello { SupervisorHello { sandbox_id: Uuid::new_v4().to_string(), instance_id: Uuid::new_v4().to_string(), + protocol_revision: SUPERVISOR_PROTOCOL_REVISION, connection_epoch: 0, supports_provider_readiness: true, } diff --git a/crates/openshell-server/src/grpc/sandbox.rs b/crates/openshell-server/src/grpc/sandbox.rs index 074b2590e0..0bee7d9929 100644 --- a/crates/openshell-server/src/grpc/sandbox.rs +++ b/crates/openshell-server/src/grpc/sandbox.rs @@ -1442,6 +1442,14 @@ pub(super) async fn handle_attach_sandbox_provider( .map_err(|e| super::persistence_error_to_status(e, "attach sandbox provider"))?; let attached = attached.load(Ordering::Relaxed); + if attached { + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); + state.sandbox_watch_bus.notify(&sandbox_id); + } let receipt = super::provider_readiness::record_provider_mutation( state, &sandbox, @@ -1565,6 +1573,14 @@ pub(super) async fn handle_detach_sandbox_provider( .map_err(|e| super::persistence_error_to_status(e, "detach sandbox provider"))?; let detached = detached.load(Ordering::Relaxed); + if detached { + crate::config_delivery::publish_sandbox_components( + state, + &sandbox_id, + crate::config_delivery::ConfigComponents::SANDBOX_AND_PROVIDER, + ); + state.sandbox_watch_bus.notify(&sandbox_id); + } let receipt = super::provider_readiness::record_provider_mutation( state, &sandbox, diff --git a/crates/openshell-server/src/lib.rs b/crates/openshell-server/src/lib.rs index 72efa01fbf..371664febe 100644 --- a/crates/openshell-server/src/lib.rs +++ b/crates/openshell-server/src/lib.rs @@ -17,6 +17,7 @@ mod auth; pub mod certgen; pub mod cli; mod compute; +mod config_delivery; pub mod config_file; mod config_update_operation; mod credentials; @@ -303,6 +304,11 @@ pub struct ServerState { /// Set once graceful gateway shutdown begins so stream handlers can /// distinguish expected transport closes from runtime failures. pub(crate) gateway_shutting_down: AtomicBool, + /// Per-sandbox scheduler for coalesced supervisor configuration delivery. + pub(crate) config_delivery_queue: config_delivery::ConfigDeliveryQueue, + + /// Routing boundary for local or remote supervisor configuration delivery. + pub(crate) supervisor_config_router: Arc, /// Stable identity for this gateway process. pub replica_id: String, @@ -370,6 +376,12 @@ fn is_benign_connection_close(error: &(dyn std::error::Error + 'static)) -> bool } impl ServerState { + /// Return the configuration delivery boundary for supervisor sessions. + #[must_use] + pub fn supervisor_config_router(&self) -> Arc { + Arc::clone(&self.supervisor_config_router) + } + /// Create new server state. #[must_use] #[allow(clippy::too_many_arguments)] @@ -420,6 +432,11 @@ impl ServerState { .oidc .as_ref() .map_or_else(String::new, |oidc| oidc.admin_role.clone()); + let supervisor_config_router: Arc = Arc::new( + config_delivery::LocalSupervisorConfigRouter::new(Arc::clone(&supervisor_sessions)), + ); + let config_delivery_queue = + config_delivery::ConfigDeliveryQueue::for_db_connections(store.max_connections()); Self { config, store, @@ -434,6 +451,8 @@ impl ServerState { settings_mutex: tokio::sync::Mutex::new(()), supervisor_sessions, gateway_shutting_down: AtomicBool::new(false), + config_delivery_queue, + supervisor_config_router, replica_id, peer_endpoint, peer_routes: Arc::new(supervisor_session::PeerRouteCache::default()), @@ -845,6 +864,10 @@ pub(crate) async fn run_server( let state = Arc::new(state); + grpc::policy::backfill_legacy_policy_history(&state) + .await + .map_err(|error| Error::execution(error.to_string()))?; + // Reconcile local-driver running intent before watchers spawn so their // first snapshots observe the post-start backend state. Explicitly stopped // sandboxes remain stopped. diff --git a/crates/openshell-server/src/persistence/mod.rs b/crates/openshell-server/src/persistence/mod.rs index 2513e80c10..352e2e31be 100644 --- a/crates/openshell-server/src/persistence/mod.rs +++ b/crates/openshell-server/src/persistence/mod.rs @@ -282,6 +282,14 @@ impl Store { matches!(self, Self::Sqlite(_)) } + /// Maximum number of pooled database connections for this backend. + pub fn max_connections(&self) -> u32 { + match self { + Self::Postgres(store) => store.max_connections(), + Self::Sqlite(store) => store.max_connections(), + } + } + /// Serialize mutations whose invariants span multiple persisted objects. /// /// `SQLite` deployments are single-replica and use only the caller's local diff --git a/crates/openshell-server/src/persistence/postgres.rs b/crates/openshell-server/src/persistence/postgres.rs index cdbcc41dd8..92fb2cc4f4 100644 --- a/crates/openshell-server/src/persistence/postgres.rs +++ b/crates/openshell-server/src/persistence/postgres.rs @@ -63,6 +63,10 @@ impl PostgresStore { Ok(Self { pool }) } + pub fn max_connections(&self) -> u32 { + self.pool.options().get_max_connections() + } + pub async fn migrate(&self) -> PersistenceResult<()> { POSTGRES_MIGRATOR .run(&self.pool) @@ -1043,6 +1047,50 @@ VALUES ($1, $2, $3, $4, $5, $6, $7, $7, $8) Ok(()) } + pub async fn put_initial_policy_revision( + &self, + record: &PolicyRecord, + workspace: &str, + ) -> PersistenceResult<()> { + let wrapped_payload = policy_payload_from_record(record)?; + let mut tx = self.pool.begin().await.map_err(|e| map_db_error(&e))?; + + let sandbox_exists = sqlx::query( + "SELECT id FROM objects WHERE object_type = 'sandbox' AND id = $1 FOR UPDATE", + ) + .bind(&record.sandbox_id) + .fetch_optional(&mut *tx) + .await + .map_err(|e| map_db_error(&e))? + .is_some(); + + if sandbox_exists { + sqlx::query( + r" +INSERT INTO objects ( + object_type, id, scope, version, status, payload, created_at_ms, updated_at_ms, workspace +) +SELECT $1, $2, $3, 1, $4, $5, $6, $6, $7 +WHERE NOT EXISTS (SELECT 1 FROM objects WHERE object_type = $1 AND scope = $3) +ON CONFLICT DO NOTHING +", + ) + .bind(POLICY_OBJECT_TYPE) + .bind(&record.id) + .bind(&record.sandbox_id) + .bind(&record.status) + .bind(wrapped_payload) + .bind(record.created_at_ms) + .bind(workspace) + .execute(&mut *tx) + .await + .map_err(|e| map_db_error(&e))?; + } + + tx.commit().await.map_err(|e| map_db_error(&e))?; + Ok(()) + } + pub async fn put_policy_revision_atomic( &self, write: &AtomicPolicyRevisionWrite, diff --git a/crates/openshell-server/src/persistence/sqlite.rs b/crates/openshell-server/src/persistence/sqlite.rs index ce269cd241..24e126e119 100644 --- a/crates/openshell-server/src/persistence/sqlite.rs +++ b/crates/openshell-server/src/persistence/sqlite.rs @@ -201,6 +201,10 @@ impl SqliteStore { self.close().await; } + pub fn max_connections(&self) -> u32 { + self.pool.options().get_max_connections() + } + pub async fn connect(url: &str) -> PersistenceResult { let is_in_memory = url.contains(":memory:") || url.contains("mode=memory"); let max_connections = if is_in_memory { 1 } else { 5 }; @@ -1273,6 +1277,36 @@ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?7, ?8) Ok(()) } + pub async fn put_initial_policy_revision( + &self, + record: &PolicyRecord, + workspace: &str, + ) -> PersistenceResult<()> { + let wrapped_payload = policy_payload_from_record(record)?; + sqlx::query( + r#" +INSERT INTO "objects" ( + "object_type", "id", "scope", "version", "status", "payload", "created_at_ms", "updated_at_ms", "workspace" +) +SELECT ?1, ?2, ?3, 1, ?4, ?5, ?6, ?6, ?7 +WHERE EXISTS (SELECT 1 FROM "objects" WHERE "object_type" = 'sandbox' AND "id" = ?3) + AND NOT EXISTS (SELECT 1 FROM "objects" WHERE "object_type" = ?1 AND "scope" = ?3) +ON CONFLICT DO NOTHING +"#, + ) + .bind(POLICY_OBJECT_TYPE) + .bind(&record.id) + .bind(&record.sandbox_id) + .bind(&record.status) + .bind(wrapped_payload) + .bind(record.created_at_ms) + .bind(workspace) + .execute(&self.pool) + .await + .map_err(|e| map_db_error(&e))?; + Ok(()) + } + pub async fn put_policy_revision_atomic( &self, write: &AtomicPolicyRevisionWrite, diff --git a/crates/openshell-server/src/persistence/tests.rs b/crates/openshell-server/src/persistence/tests.rs index 7ba0bd1245..6634d3072f 100644 --- a/crates/openshell-server/src/persistence/tests.rs +++ b/crates/openshell-server/src/persistence/tests.rs @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -use super::{ObjectListQuery, ObjectType, PersistenceError, Store, generate_name, test_store}; +use super::{ + ObjectListQuery, ObjectType, PersistenceError, PolicyRecord, Store, generate_name, test_store, +}; use crate::policy_store::{AtomicPolicyRevisionWrite, PolicyStoreExt}; use openshell_core::proto::datamodel::v1::ObjectMeta as ProtoObjectMeta; use openshell_core::proto::{ObjectForTest, Sandbox, SandboxPolicy, SandboxSpec}; @@ -1342,6 +1344,85 @@ fn policy_test_sandbox(id: &str, name: &str) -> Sandbox { } } +#[tokio::test] +async fn initial_policy_history_is_insert_only() { + assert_initial_policy_history_is_insert_only(&test_store().await).await; +} + +#[tokio::test] +#[ignore = "requires OPENSHELL_TEST_POSTGRES_URL pointing to a test database"] +async fn postgres_initial_policy_history_is_insert_only() { + let url = std::env::var("OPENSHELL_TEST_POSTGRES_URL").expect("test database URL"); + let store = Store::connect(&url).await.unwrap(); + assert_initial_policy_history_is_insert_only(&store).await; +} + +async fn assert_initial_policy_history_is_insert_only(store: &Store) { + let id = uuid::Uuid::new_v4().to_string(); + let sandbox = policy_test_sandbox(&id, &id); + let record = PolicyRecord { + id: uuid::Uuid::new_v4().to_string(), + sandbox_id: id.clone(), + version: 1, + policy_payload: SandboxPolicy::default().encode_to_vec(), + policy_hash: "initial-hash".into(), + status: "loaded".into(), + load_error: None, + created_at_ms: 1, + loaded_at_ms: None, + provenance: StdHashMap::new(), + }; + + store + .put_initial_policy_revision(&record, "default") + .await + .unwrap(); + assert!(store.get_latest_policy(&id).await.unwrap().is_none()); + + store.put_message(&sandbox).await.unwrap(); + let (first, second) = tokio::join!( + store.put_initial_policy_revision(&record, "default"), + store.put_initial_policy_revision(&record, "default"), + ); + first.unwrap(); + second.unwrap(); + let initial = store.get_latest_policy(&id).await.unwrap().unwrap(); + assert_eq!(initial.status, "loaded"); + assert_eq!(initial.policy_hash, record.policy_hash); + assert_eq!(store.list_policies(&id, 10, 0).await.unwrap().len(), 1); + + store + .update_policy_status(&id, 1, "failed", Some("apply failed"), None) + .await + .unwrap(); + store + .put_initial_policy_revision(&record, "default") + .await + .unwrap(); + let failed = store.get_latest_policy(&id).await.unwrap().unwrap(); + assert_eq!(failed.status, "failed"); + assert_eq!(failed.load_error.as_deref(), Some("apply failed")); + + store + .put_policy_revision( + &uuid::Uuid::new_v4().to_string(), + &id, + "default", + 2, + &record.policy_payload, + "new-hash", + ) + .await + .unwrap(); + store + .put_initial_policy_revision(&record, "default") + .await + .unwrap(); + let latest = store.get_latest_policy(&id).await.unwrap().unwrap(); + assert_eq!(latest.version, 2); + assert_eq!(store.list_policies(&id, 10, 0).await.unwrap().len(), 2); +} + #[tokio::test] async fn policy_atomic_write_commits_revision_provenance_and_sandbox_projection() { let store = test_store().await; diff --git a/crates/openshell-server/src/policy_store.rs b/crates/openshell-server/src/policy_store.rs index 8ac1092802..c610f21fb8 100644 --- a/crates/openshell-server/src/policy_store.rs +++ b/crates/openshell-server/src/policy_store.rs @@ -136,6 +136,14 @@ pub fn project_policy_revision_onto_sandbox( } pub trait PolicyStoreExt { + /// Insert version-one policy history when the sandbox still has no policy + /// revisions. Existing history and apply status are left untouched. + async fn put_initial_policy_revision( + &self, + record: &PolicyRecord, + workspace: &str, + ) -> PersistenceResult<()>; + async fn put_policy_revision( &self, id: &str, @@ -270,6 +278,17 @@ pub trait PolicyStoreExt { } impl PolicyStoreExt for Store { + async fn put_initial_policy_revision( + &self, + record: &PolicyRecord, + workspace: &str, + ) -> PersistenceResult<()> { + match self { + Self::Postgres(store) => store.put_initial_policy_revision(record, workspace).await, + Self::Sqlite(store) => store.put_initial_policy_revision(record, workspace).await, + } + } + async fn put_policy_revision( &self, id: &str, diff --git a/crates/openshell-server/src/provider_refresh.rs b/crates/openshell-server/src/provider_refresh.rs index c7d98c9917..296795640b 100644 --- a/crates/openshell-server/src/provider_refresh.rs +++ b/crates/openshell-server/src/provider_refresh.rs @@ -1918,14 +1918,25 @@ pub fn spawn_refresh_worker(state: std::sync::Arc, interval: ticker.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); loop { ticker.tick().await; - if let Err(err) = Box::pin(run_refresh_worker_tick( + match Box::pin(run_refresh_worker_tick( state.store.as_ref(), Some(&state.credentials), Some(&state.compute), )) .await { - warn!(error = %err, "provider credential refresh worker tick failed"); + Ok(workspaces) => { + for workspace in workspaces { + crate::config_delivery::publish_workspace_components( + &state, + &workspace, + crate::config_delivery::ConfigComponents::ALL, + ); + } + } + Err(err) => { + warn!(error = %err, "provider credential refresh worker tick failed"); + } } } }); @@ -1935,7 +1946,8 @@ async fn run_refresh_worker_tick( store: &Store, credentials: Option<&crate::credentials::CredentialRuntime>, compute: Option<&crate::compute::ComputeRuntime>, -) -> Result<(), Status> { +) -> Result, Status> { + let changed_workspaces = std::collections::HashSet::new(); let now_ms = current_time_ms(); let states = list_all_refresh_states(store).await?; let watched_count = states.len(); @@ -1955,7 +1967,7 @@ async fn run_refresh_worker_tick( .iter() .any(|state| refresh_state_has_work(state, now_ms)) { - return Ok(()); + return Ok(changed_workspaces); } let span = tracing::info_span!( "refresh", @@ -1963,8 +1975,10 @@ async fn run_refresh_worker_tick( watched_count, due_count, ); - Box::pin(refresh_states(store, credentials, compute, states, now_ms).instrument(span)).await; - Ok(()) + Ok( + Box::pin(refresh_states(store, credentials, compute, states, now_ms).instrument(span)) + .await, + ) } fn refresh_state_has_work(state: &StoredProviderCredentialRefreshState, now_ms: i64) -> bool { @@ -1984,7 +1998,8 @@ async fn refresh_states( compute: Option<&crate::compute::ComputeRuntime>, states: Vec, now_ms: i64, -) { +) -> std::collections::HashSet { + let mut changed_workspaces = std::collections::HashSet::new(); for state in states { if state .metadata @@ -2014,6 +2029,8 @@ async fn refresh_states( error = %err, "failed to finalize tombstoned provider refresh; retrying on the next sweep" ); + } else { + changed_workspaces.insert(state.object_workspace().to_string()); } continue; } @@ -2097,8 +2114,11 @@ async fn refresh_states( error = %err, "provider credential refresh failed" ); + } else { + changed_workspaces.insert(state.object_workspace().to_string()); } } + changed_workspaces } #[cfg(test)] diff --git a/crates/openshell-server/src/storage_proto.rs b/crates/openshell-server/src/storage_proto.rs index e6d8730aa0..eef3bc0fa3 100644 --- a/crates/openshell-server/src/storage_proto.rs +++ b/crates/openshell-server/src/storage_proto.rs @@ -123,13 +123,14 @@ mod tests { // Unspecified (treated as Never), zero count, and absent timestamps. // ProviderProfileFile is reachable from stored provider profiles. Its // additive declaration changes the durable and public/durable overlap - // inventories; the provider-environment file map is public-only. The + // inventories; the provider-environment file map and peer configuration + // hint are public-only. The // request has no provider-file capability field: older supervisors ignore // the additive file map while retaining the rest of the response. // Service authorization also extends both schemas additively. Legacy // payloads retain the safe Strip default. const PUBLIC_RPC_SCHEMA_SHA256: &str = - "2e156c6ad3c8eb51bcd30dc13b173fe339b38207a1b1f98f7be2e0cad8e3bd45"; + "73d5454909634839151b6d47fe4b62793d5426a783517541e91972766cf81aef"; const DURABLE_SCHEMA_SHA256: &str = "38165d9d76f49fcfe98a12f241e032838a2376c1d1a87ea2796fd33b9b1a3541"; const PUBLIC_DURABLE_OVERLAP_SHA256: &str = @@ -175,6 +176,9 @@ mod tests { "openshell.v1.OpenShell/PeerReportEndpointStatus|.openshell.v1.ReportEndpointStatusRequest|.openshell.v1.ReportEndpointStatusResponse|false|false", "openshell.v1.OpenShell/PeerReportProviderReadiness|.openshell.v1.ReportProviderReadinessRequest|.openshell.v1.ReportProviderReadinessResponse|false|false", ]; + const PEER_CONFIG_RPC_SIGNATURES: [&str; 1] = [ + "openshell.v1.OpenShell/PeerNotifyConfigUpdate|.openshell.v1.PeerConfigUpdateHintRequest|.openshell.v1.PeerConfigUpdateHintResponse|false|false", + ]; // Synthetic SandboxSpec bytes with log level, provider, and command fields, // emitted before the gateway-owned attachment epoch field was introduced. const PRE_READINESS_SANDBOX_SPEC: &str = @@ -539,14 +543,24 @@ mod tests { "peer owner RPC is missing or changed: {signature}" ); } + for signature in PEER_CONFIG_RPC_SIGNATURES { + assert!( + methods.iter().any(|method| method == signature), + "peer config RPC is missing or changed: {signature}" + ); + } assert_eq!( compiled_method_count, - 102 + PROVIDER_READINESS_RPC_SIGNATURES.len() + PEER_OWNER_RPC_SIGNATURES.len(), + 102 + PROVIDER_READINESS_RPC_SIGNATURES.len() + + PEER_OWNER_RPC_SIGNATURES.len() + + PEER_CONFIG_RPC_SIGNATURES.len(), "classify every compiled RPC" ); assert_eq!( methods.len(), - 77 + PROVIDER_READINESS_RPC_SIGNATURES.len() + PEER_OWNER_RPC_SIGNATURES.len(), + 77 + PROVIDER_READINESS_RPC_SIGNATURES.len() + + PEER_OWNER_RPC_SIGNATURES.len() + + PEER_CONFIG_RPC_SIGNATURES.len(), "inventory every public gateway RPC" ); assert_eq!( @@ -554,7 +568,9 @@ mod tests { .iter() .filter(|method| method.starts_with("openshell.v1.OpenShell/")) .count(), - 77 + PROVIDER_READINESS_RPC_SIGNATURES.len() + PEER_OWNER_RPC_SIGNATURES.len() + 77 + PROVIDER_READINESS_RPC_SIGNATURES.len() + + PEER_OWNER_RPC_SIGNATURES.len() + + PEER_CONFIG_RPC_SIGNATURES.len() ); assert!(methods.iter().all(|method| !method.contains(".storage."))); @@ -598,7 +614,7 @@ mod tests { overlap_hash.as_str(), ), ( - (306, 27), + (321, 28), (93, 21), (81, 21), PUBLIC_RPC_SCHEMA_SHA256, diff --git a/crates/openshell-server/src/supervisor_owner.rs b/crates/openshell-server/src/supervisor_owner.rs index a517bce0fa..dfd2bcb000 100644 --- a/crates/openshell-server/src/supervisor_owner.rs +++ b/crates/openshell-server/src/supervisor_owner.rs @@ -3,12 +3,14 @@ //! Shared supervisor-session ownership index for HA gateway replicas. -use crate::persistence::{PersistenceError, Store, WriteCondition}; +use crate::persistence::{ObjectCursor, ObjectRecord, PersistenceError, Store, WriteCondition}; use openshell_core::time::now_ms; use serde::{Deserialize, Serialize}; +use std::collections::HashSet; use std::sync::Arc; use std::time::{Duration, Instant}; use thiserror::Error; +use tracing::warn; const OWNER_OBJECT_TYPE: &str = "supervisor_session_owner"; @@ -211,18 +213,48 @@ impl SupervisorOwnerIndex { return Ok(None); }; - let payload: OwnerPayload = serde_json::from_slice(&record.payload) - .map_err(|err| PersistenceError::Decode(err.to_string()))?; - Ok(Some(OwnerRecord { - session_id: payload.session_id, - supervisor_instance_id: payload.supervisor_instance_id, - connection_epoch: payload.connection_epoch, - owner_replica_id: payload.owner_replica_id, - owner_peer_endpoint: payload.owner_peer_endpoint, - connected_at_ms: payload.connected_at_ms, - updated_at_ms: record.updated_at_ms, - resource_version: record.resource_version, - })) + Ok(Some(decode_owner_record(&record)?.1)) + } + + /// Return distinct reachable peer endpoints from fresh owner records. + /// The scan uses bounded pages and retains only one endpoint per peer. + pub async fn list_fresh_peer_endpoints( + &self, + local_replica_id: &str, + ) -> Result, OwnerError> { + const PAGE_SIZE: u32 = 256; + let mut after = None; + let mut endpoints = HashSet::new(); + loop { + let page = self + .store + .list_by_type_after(OWNER_OBJECT_TYPE, after.as_ref(), PAGE_SIZE) + .await?; + if page.is_empty() { + break; + } + after = page.last().map(ObjectCursor::from); + for record in &page { + match decode_owner_record(record) { + Ok((_, owner)) + if owner.is_fresh(self.ttl) + && owner.owner_replica_id != local_replica_id + && (owner.owner_peer_endpoint.starts_with("http://") + || owner.owner_peer_endpoint.starts_with("https://")) => + { + endpoints.insert(owner.owner_peer_endpoint); + } + Ok(_) => {} + Err(error) => { + warn!(record_id = %record.id, error = %error, "skipping invalid supervisor owner record"); + } + } + } + if page.len() < PAGE_SIZE as usize { + break; + } + } + Ok(endpoints.into_iter().collect()) } async fn write_payload( @@ -255,6 +287,29 @@ impl SupervisorOwnerIndex { } } +fn decode_owner_record(record: &ObjectRecord) -> Result<(String, OwnerRecord), OwnerError> { + let payload: OwnerPayload = serde_json::from_slice(&record.payload) + .map_err(|err| PersistenceError::Decode(err.to_string()))?; + if payload.sandbox_id != record.name || record.id != owner_object_id(&payload.sandbox_id) { + return Err(OwnerError::Store(PersistenceError::Decode( + "supervisor owner identity mismatch".to_string(), + ))); + } + Ok(( + payload.sandbox_id, + OwnerRecord { + session_id: payload.session_id, + supervisor_instance_id: payload.supervisor_instance_id, + connection_epoch: payload.connection_epoch, + owner_replica_id: payload.owner_replica_id, + owner_peer_endpoint: payload.owner_peer_endpoint, + connected_at_ms: payload.connected_at_ms, + updated_at_ms: record.updated_at_ms, + resource_version: record.resource_version, + }, + )) +} + fn can_supersede( existing: &OwnerRecord, supervisor_instance_id: &str, @@ -348,6 +403,33 @@ mod tests { assert_eq!(record.owner_replica_id, "gw-1"); } + #[tokio::test] + async fn fresh_peer_scan_deduplicates_and_excludes_local_owner() { + let index = test_index(OWNER_TTL).await; + for (sandbox, replica, endpoint) in [ + ("sbx-1", "gw-1", "http://gw-1"), + ("sbx-2", "gw-2", "http://gw-2"), + ("sbx-3", "gw-2", "http://gw-2"), + ("sbx-4", "gw-3", "local://unreachable"), + ] { + index + .publish(sandbox, "session", sandbox, 1, replica, endpoint) + .await + .unwrap(); + } + for index_number in 0..260 { + let sandbox = format!("paged-sandbox-{index_number}"); + index + .publish(&sandbox, "session", &sandbox, 1, "gw-2", "http://gw-2") + .await + .unwrap(); + } + assert_eq!( + index.list_fresh_peer_endpoints("gw-1").await.unwrap(), + vec!["http://gw-2"] + ); + } + #[tokio::test] async fn publish_does_not_collide_with_sandbox_object_id() { let index = test_index(OWNER_TTL).await; diff --git a/crates/openshell-server/src/supervisor_session.rs b/crates/openshell-server/src/supervisor_session.rs index 7fc11594af..61d2acd5e2 100644 --- a/crates/openshell-server/src/supervisor_session.rs +++ b/crates/openshell-server/src/supervisor_session.rs @@ -7,6 +7,8 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; +use metrics::counter; +use prost::Message; use tokio::sync::{OwnedRwLockReadGuard, RwLock, mpsc, oneshot, watch}; use tokio_stream::wrappers::ReceiverStream; use tonic::metadata::{Ascii, MetadataValue}; @@ -16,17 +18,25 @@ use tracing::{debug, info, warn}; use uuid::Uuid; use openshell_core::proto::{ - GatewayMessage, GetSandboxProviderStatusRequest, GetSandboxProviderStatusResponse, + ConfigUpdate, GatewayMessage, GetSandboxProviderStatusRequest, + GetSandboxProviderStatusResponse, PeerConfigUpdateHintRequest, PeerConfigUpdateHintResponse, PeerRelayFrame, PeerRelayInit, ProviderReadinessObservation, RelayFrame, RelayInit, RelayOpen, ReportEndpointStatusRequest, ReportEndpointStatusResponse, ReportMainProcessExitRequest, ReportMainProcessExitResponse, ReportProviderReadinessRequest, ReportProviderReadinessResponse, Sandbox, SandboxPhase, SessionAccepted, SshRelayTarget, SupervisorHello, SupervisorMessage, - gateway_message, open_shell_client, peer_relay_frame, relay_open, supervisor_message, + config_update, gateway_message, open_shell_client, peer_relay_frame, relay_open, + supervisor_message, }; +use openshell_core::proto::{LEGACY_SUPERVISOR_PROTOCOL_REVISION, SUPERVISOR_PROTOCOL_REVISION}; use openshell_core::transport_errors::is_expected_transport_close_status; use crate::ServerState; use crate::auth::principal::Principal; +use crate::config_delivery::{ + DeliveryDisposition, MAX_SUPERVISOR_CONFIG_MESSAGE_BYTES, SupervisorConfigMessage, +}; +#[cfg(test)] +use crate::config_delivery::{LocalSupervisorConfigRouter, SupervisorConfigRouter}; use crate::grpc::provider_readiness::ProviderReadinessEvidence; use crate::persistence::ObjectId; use crate::supervisor_owner::{OWNER_TTL, OwnerError, OwnerGuard, SupervisorOwnerIndex}; @@ -273,7 +283,9 @@ struct LiveSession { /// Uniquely identifies this session instance. Used by cleanup to avoid /// removing a session that has since been superseded by a reconnect. session_id: String, + config_push_capable: bool, tx: mpsc::Sender, + config_sequences: ConfigSequences, /// Fires when this session is superseded by a reconnect so the old session /// task can exit promptly — dropping its own `tx` clone and closing the /// outbound stream. Without this, a concurrent `open_relay` that grabbed @@ -299,6 +311,12 @@ struct LiveSession { connected_at: Instant, } +#[derive(Debug, Default)] +struct ConfigSequences { + sandbox_config: u64, + provider_environment: u64, +} + /// Idempotency state for tool server endpoint-status reports from one live supervisor. #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct EndpointReportCursor { @@ -403,6 +421,17 @@ impl SupervisorSessionRegistry { session_id: String, tx: mpsc::Sender, shutdown: oneshot::Sender<()>, + ) -> bool { + self.register_with_config_push(sandbox_id, session_id, tx, shutdown, true) + } + + pub fn register_with_config_push( + &self, + sandbox_id: String, + session_id: String, + tx: mpsc::Sender, + shutdown: oneshot::Sender<()>, + config_push_capable: bool, ) -> bool { let mut sessions = self.sessions.lock().unwrap(); let previous = sessions.remove(&sandbox_id); @@ -411,7 +440,9 @@ impl SupervisorSessionRegistry { LiveSession { sandbox_id, session_id, + config_push_capable, tx, + config_sequences: ConfigSequences::default(), shutdown, terminal_delivery_finalized: false, endpoint_status_initialized: false, @@ -527,6 +558,82 @@ impl SupervisorSessionRegistry { true } + pub(crate) fn connected_sandbox_ids(&self) -> Vec { + self.sessions + .lock() + .unwrap() + .iter() + .filter(|(_, session)| session.config_push_capable) + .map(|(sandbox_id, _)| sandbox_id.clone()) + .collect() + } + + pub(crate) fn is_config_push_capable(&self, sandbox_id: &str) -> bool { + self.sessions + .lock() + .unwrap() + .get(sandbox_id) + .is_some_and(|session| session.config_push_capable) + } + + pub(crate) fn deliver_config( + &self, + sandbox_id: &str, + message: SupervisorConfigMessage, + ) -> DeliveryDisposition { + let component_name = message.component_name(); + let mut sessions = self.sessions.lock().unwrap(); + let Some(session) = sessions.get_mut(sandbox_id) else { + return DeliveryDisposition::NoActiveSession; + }; + if !session.config_push_capable { + return DeliveryDisposition::UnsupportedSession; + } + let sequence = match &message { + SupervisorConfigMessage::SandboxConfig(_) => { + &mut session.config_sequences.sandbox_config + } + SupervisorConfigMessage::ProviderEnvironment(_) => { + &mut session.config_sequences.provider_environment + } + }; + *sequence = sequence.saturating_add(1); + let component_sequence = *sequence; + + let component = match message { + SupervisorConfigMessage::SandboxConfig(snapshot) => { + config_update::Component::SandboxConfig(*snapshot) + } + SupervisorConfigMessage::ProviderEnvironment(snapshot) => { + config_update::Component::ProviderEnvironment(snapshot) + } + }; + let gateway_message = GatewayMessage { + payload: Some(gateway_message::Payload::ConfigUpdate(ConfigUpdate { + update_id: Uuid::new_v4().to_string(), + component_sequence, + component: Some(component), + })), + }; + + if gateway_message.encoded_len() > MAX_SUPERVISOR_CONFIG_MESSAGE_BYTES { + return DeliveryDisposition::PayloadTooLarge; + } + + match session.tx.try_send(gateway_message) { + Ok(()) => DeliveryDisposition::Enqueued, + Err(mpsc::error::TrySendError::Full(_)) => { + warn!( + sandbox_id = %sandbox_id, + component = component_name, + "supervisor configuration queue is full" + ); + DeliveryDisposition::QueueFull + } + Err(mpsc::error::TrySendError::Closed(_)) => DeliveryDisposition::SessionClosed, + } + } + pub fn is_current_session(&self, sandbox_id: &str, session_id: &str) -> bool { self.sessions .lock() @@ -1049,17 +1156,13 @@ fn owner_error_to_status(err: OwnerError) -> Status { async fn require_persisted_sandbox( store: &Arc, sandbox_id: &str, -) -> Result<(), Status> { +) -> Result { let sandbox = store .get_message::(sandbox_id) .await .map_err(|err| Status::internal(format!("failed to load sandbox: {err}")))?; - if sandbox.is_none() { - return Err(Status::not_found("sandbox not found")); - } - - Ok(()) + sandbox.ok_or_else(|| Status::not_found("sandbox not found")) } // --------------------------------------------------------------------------- @@ -1348,6 +1451,19 @@ async fn peer_rpc_client( )) } +pub(crate) async fn forward_config_hint_to_peer( + state: &Arc, + endpoint: &str, + request: PeerConfigUpdateHintRequest, +) -> Result { + let mut client = peer_rpc_client(state, endpoint).await?; + client + .peer_notify_config_update(request) + .await + .map(Response::into_inner) + .inspect_err(|_| state.peer_routes.evict_channel(endpoint)) +} + pub(crate) async fn remote_supervisor_owner( state: &Arc, sandbox_id: &str, @@ -1869,10 +1985,42 @@ pub async fn handle_connect_supervisor( if sandbox_id.is_empty() { return Err(Status::invalid_argument("sandbox_id is required")); } + validate_protocol_revision(&sandbox_id, hello.protocol_revision)?; if let Some(principal) = principal.as_ref() { crate::auth::guard::ensure_sandbox_principal_scope(principal, &sandbox_id)?; } - require_persisted_sandbox(&state.store, &sandbox_id).await?; + let sandbox = require_persisted_sandbox(&state.store, &sandbox_id).await?; + + let bootstrap = if state.config.config_delivery_mode + == openshell_core::config::ConfigDeliveryMode::Poll + || hello.protocol_revision == LEGACY_SUPERVISOR_PROTOCOL_REVISION + { + None + } else { + match crate::config_delivery::build_config_bootstrap(state, &sandbox).await { + Ok(bootstrap) => { + counter!( + "openshell_supervisor_config_bootstrap_total", + "outcome" => "built" + ) + .increment(1); + Some(bootstrap) + } + Err(error) => { + counter!( + "openshell_supervisor_config_bootstrap_total", + "outcome" => "build_failed" + ) + .increment(1); + warn!( + sandbox_id = %sandbox_id, + error_code = ?error.code(), + "failed to build supervisor configuration bootstrap" + ); + None + } + } + }; // Validate readiness identities before replacing a healthy session. Older // supervisors remain usable but cannot assert provider installation. let provider_readiness = ProviderReadinessEvidence::from_hello(&hello)?; @@ -1885,6 +2033,7 @@ pub async fn handle_connect_supervisor( state, inbound, hello, + bootstrap, provider_readiness, session_lifetime, )) @@ -1896,6 +2045,7 @@ async fn establish_supervisor_session( state: Arc, mut inbound: tonic::Streaming, hello: SupervisorHello, + bootstrap: Option, provider_readiness: ProviderReadinessEvidence, session_lifetime: OwnedRwLockReadGuard<()>, ) -> Result< @@ -1931,14 +2081,47 @@ async fn establish_supervisor_session( "supervisor session: accepted" ); - // Step 2: Create and register the outbound channel. + // Step 2: Queue SessionAccepted before the session becomes routable. This + // keeps a concurrent ConfigUpdate from becoming the first stream message. let (tx, rx) = mpsc::channel::(64); let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>(); - let superseded = state.supervisor_sessions.register( + let mut accepted = GatewayMessage { + payload: Some(gateway_message::Payload::SessionAccepted(SessionAccepted { + session_id: session_id.clone(), + bootstrap, + protocol_revision: SUPERVISOR_PROTOCOL_REVISION, + heartbeat_interval: openshell_core::time::duration_from_std(Duration::from_secs( + u64::from(HEARTBEAT_INTERVAL_SECS), + )) + .ok(), + })), + }; + if accepted.encoded_len() > MAX_SUPERVISOR_CONFIG_MESSAGE_BYTES { + counter!( + "openshell_supervisor_config_bootstrap_total", + "outcome" => "payload_too_large" + ) + .increment(1); + let Some(gateway_message::Payload::SessionAccepted(accepted_payload)) = + accepted.payload.as_mut() + else { + unreachable!("constructed SessionAccepted payload") + }; + accepted_payload.bootstrap = None; + } + if tx.send(accepted).await.is_err() { + if let Err(err) = owner_index.release_if_current(&owner_guard).await { + warn!(sandbox_id = %sandbox_id, session_id = %session_id, error = %err, "supervisor session: failed to release owner after accept queue failure"); + } + return Err(Status::internal("failed to send session accepted")); + } + + let superseded = state.supervisor_sessions.register_with_config_push( sandbox_id.clone(), session_id.clone(), tx.clone(), shutdown_tx, + hello.protocol_revision == SUPERVISOR_PROTOCOL_REVISION, ); if superseded { info!( @@ -1991,28 +2174,6 @@ async fn establish_supervisor_session( return Err(error); } - // Step 3: Send SessionAccepted. - let accepted = GatewayMessage { - payload: Some(gateway_message::Payload::SessionAccepted(SessionAccepted { - session_id: session_id.clone(), - heartbeat_interval: openshell_core::time::duration_from_std(Duration::from_secs( - u64::from(HEARTBEAT_INTERVAL_SECS), - )) - .ok(), - })), - }; - if tx.send(accepted).await.is_err() { - // Only evict ourselves — a faster reconnect may already have - // superseded this registration. - state - .supervisor_sessions - .remove_if_current(&sandbox_id, &session_id); - if let Err(err) = owner_index.release_if_current(&owner_guard).await { - warn!(sandbox_id = %sandbox_id, session_id = %session_id, error = %err, "supervisor session: failed to release owner after accept send failure"); - } - return Err(Status::internal("failed to send session accepted")); - } - if let Err(err) = state .compute .supervisor_session_connected(&sandbox_id, &hello.instance_id) @@ -2111,6 +2272,23 @@ async fn establish_supervisor_session( Ok(Response::new(stream)) } +fn validate_protocol_revision(sandbox_id: &str, supervisor_revision: u32) -> Result<(), Status> { + match supervisor_revision { + SUPERVISOR_PROTOCOL_REVISION => Ok(()), + LEGACY_SUPERVISOR_PROTOCOL_REVISION => { + counter!("openshell_supervisor_protocol_legacy_sessions_total").increment(1); + warn!( + sandbox_id = %sandbox_id, + "supervisor session: supervisor predates the protocol handshake; recreate the sandbox before the next gateway upgrade" + ); + Ok(()) + } + other => Err(Status::failed_precondition(format!( + "supervisor protocol revision mismatch: gateway requires {SUPERVISOR_PROTOCOL_REVISION}, supervisor offered {other}" + ))), + } +} + pub async fn handle_report_main_process_exit( state: &Arc, request: Request, @@ -2339,6 +2517,22 @@ async fn handle_supervisor_message( "supervisor session: relay closed by supervisor" ); } + Some(supervisor_message::Payload::ConfigUpdateResult(result)) => { + debug!( + sandbox_id = %sandbox_id, + session_id = %session_id, + component_sequence = result.component_sequence, + "supervisor session: ignoring configuration result while polling remains authoritative" + ); + } + Some(supervisor_message::Payload::ConfigBootstrapResult(result)) => { + debug!( + sandbox_id = %sandbox_id, + session_id = %session_id, + result_count = result.results.len(), + "supervisor session: ignoring bootstrap result while polling remains authoritative" + ); + } _ => { warn!( sandbox_id = %sandbox_id, @@ -2360,6 +2554,327 @@ mod tests { use crate::auth::identity::{Identity, IdentityProvider}; use crate::auth::principal::{SandboxIdentitySource, SandboxPrincipal, UserPrincipal}; use crate::persistence::Store; + use openshell_core::proto::{ + ProviderEnvironmentSnapshot, ProviderEnvironmentValue, SandboxConfigRevision, + SandboxConfigSnapshot, + }; + use prost::Message; + + #[test] + fn configuration_stream_messages_round_trip() { + let bootstrap = GatewayMessage { + payload: Some(gateway_message::Payload::SessionAccepted(SessionAccepted { + session_id: "session-1".into(), + heartbeat_interval: openshell_core::time::duration_from_std(Duration::from_secs( + 15, + )) + .ok(), + bootstrap: Some(openshell_core::proto::ConfigBootstrap { + sandbox_config: Some(SandboxConfigSnapshot::default()), + provider_environment: Some(ProviderEnvironmentSnapshot::default()), + }), + protocol_revision: SUPERVISOR_PROTOCOL_REVISION, + })), + }; + let updates = [ + config_update::Component::SandboxConfig(SandboxConfigSnapshot::default()), + config_update::Component::ProviderEnvironment(ProviderEnvironmentSnapshot::default()), + ] + .into_iter() + .enumerate() + .map(|(index, component)| GatewayMessage { + payload: Some(gateway_message::Payload::ConfigUpdate(ConfigUpdate { + update_id: format!("update-{index}"), + component_sequence: u64::try_from(index + 1).unwrap(), + component: Some(component), + })), + }); + + for original in std::iter::once(bootstrap).chain(updates) { + let decoded = GatewayMessage::decode(original.encode_to_vec().as_slice()).unwrap(); + assert_eq!(decoded, original); + } + + let result = SupervisorMessage { + payload: Some(supervisor_message::Payload::ConfigUpdateResult( + openshell_core::proto::ConfigUpdateResult { + update_id: "update-1".into(), + component_sequence: 4, + result: Some(openshell_core::proto::ConfigComponentApplyResult { + component: openshell_core::proto::ConfigComponent::SandboxConfig.into(), + requested_revision: Some(openshell_core::proto::ConfigSnapshotRevision { + component: Some( + openshell_core::proto::config_snapshot_revision::Component::SandboxConfig( + SandboxConfigRevision { + config_revision: 7, + policy_version: 3, + ..Default::default() + }, + ), + ), + }), + applied_revision: Some(openshell_core::proto::ConfigSnapshotRevision { + component: Some( + openshell_core::proto::config_snapshot_revision::Component::SandboxConfig( + SandboxConfigRevision { + config_revision: 7, + policy_version: 3, + ..Default::default() + }, + ), + ), + }), + outcome: openshell_core::proto::ConfigApplyOutcome::Applied.into(), + failure: None, + }), + }, + )), + }; + let decoded = SupervisorMessage::decode(result.encode_to_vec().as_slice()).unwrap(); + assert_eq!(decoded, result); + } + + #[test] + fn supervisor_protocol_revision_accepts_current_and_legacy_peers() { + assert!(validate_protocol_revision("sb-1", SUPERVISOR_PROTOCOL_REVISION).is_ok()); + assert!(validate_protocol_revision("sb-1", LEGACY_SUPERVISOR_PROTOCOL_REVISION).is_ok()); + } + + async fn state_with_sandbox(sandbox_id: &str) -> Arc { + let state = crate::grpc::test_support::test_server_state().await; + state + .store + .put_message(&sandbox_record(sandbox_id, sandbox_id)) + .await + .unwrap(); + state + } + + async fn first_gateway_message( + harness: &mut crate::grpc::test_support::SupervisorStreamHarness, + ) -> GatewayMessage { + tokio::time::timeout(Duration::from_secs(5), harness.inbound.message()) + .await + .expect("gateway response before timeout") + .expect("stream open") + .expect("gateway message") + } + + #[tokio::test] + async fn legacy_supervisor_without_protocol_revision_is_accepted() { + let state = state_with_sandbox("sb-legacy").await; + let mut harness = crate::grpc::test_support::connect_supervisor_stream( + &state, + "sb-legacy", + LEGACY_SUPERVISOR_PROTOCOL_REVISION, + ) + .await + .expect("legacy supervisor must connect"); + + let Some(gateway_message::Payload::SessionAccepted(accepted)) = + first_gateway_message(&mut harness).await.payload + else { + panic!("expected SessionAccepted"); + }; + assert_eq!(accepted.protocol_revision, SUPERVISOR_PROTOCOL_REVISION); + assert!( + state + .supervisor_sessions + .is_current_session("sb-legacy", &accepted.session_id) + ); + } + + #[tokio::test] + async fn unknown_supervisor_protocol_revision_is_rejected() { + let state = state_with_sandbox("sb-future").await; + let Err(status) = crate::grpc::test_support::connect_supervisor_stream( + &state, + "sb-future", + SUPERVISOR_PROTOCOL_REVISION + 1, + ) + .await + else { + panic!("mismatched revision must be rejected"); + }; + + assert_eq!(status.code(), tonic::Code::FailedPrecondition); + assert!(status.message().contains("revision mismatch")); + assert!(state.supervisor_sessions.connected_sandbox_ids().is_empty()); + } + + #[test] + fn supervisor_protocol_revision_rejects_unknown_peers() { + let error = + validate_protocol_revision("sb-1", SUPERVISOR_PROTOCOL_REVISION + 1).unwrap_err(); + assert_eq!(error.code(), tonic::Code::FailedPrecondition); + assert!(error.message().contains("revision mismatch")); + } + + #[tokio::test] + async fn config_router_reports_missing_session() { + let router = LocalSupervisorConfigRouter::new(Arc::new(SupervisorSessionRegistry::new())); + assert_eq!( + router + .deliver( + "missing", + SupervisorConfigMessage::SandboxConfig(Box::default()), + ) + .await, + DeliveryDisposition::NoActiveSession + ); + } + + #[tokio::test] + async fn config_router_assigns_sequences_per_component() { + let registry = Arc::new(SupervisorSessionRegistry::new()); + let router = LocalSupervisorConfigRouter::new(Arc::clone(®istry)); + let (tx, mut rx) = mpsc::channel(4); + let (shutdown_tx, _shutdown_rx) = oneshot::channel(); + registry.register("sb-1".into(), "session-1".into(), tx, shutdown_tx); + + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::SandboxConfig(Box::default()), + ) + .await, + DeliveryDisposition::Enqueued + ); + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::SandboxConfig(Box::default()), + ) + .await, + DeliveryDisposition::Enqueued + ); + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::ProviderEnvironment( + ProviderEnvironmentSnapshot::default(), + ), + ) + .await, + DeliveryDisposition::Enqueued + ); + + let first = rx.recv().await.expect("first config update"); + let second = rx.recv().await.expect("second config update"); + let third = rx.recv().await.expect("provider config update"); + let sequence = |message: GatewayMessage| match message.payload { + Some(gateway_message::Payload::ConfigUpdate(update)) => update.component_sequence, + other => panic!("expected config update, got {other:?}"), + }; + assert_eq!(sequence(first), 1); + assert_eq!(sequence(second), 2); + assert_eq!(sequence(third), 1); + } + + #[tokio::test] + async fn config_router_uses_replacement_session() { + let registry = Arc::new(SupervisorSessionRegistry::new()); + let router = LocalSupervisorConfigRouter::new(Arc::clone(®istry)); + let (old_tx, mut old_rx) = mpsc::channel(2); + let (old_shutdown_tx, _old_shutdown_rx) = oneshot::channel(); + registry.register("sb-1".into(), "old-session".into(), old_tx, old_shutdown_tx); + + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::SandboxConfig(Box::default()), + ) + .await, + DeliveryDisposition::Enqueued + ); + let old_update = old_rx.recv().await.expect("old-session config update"); + let Some(gateway_message::Payload::ConfigUpdate(old_update)) = old_update.payload else { + panic!("expected config update"); + }; + assert_eq!(old_update.component_sequence, 1); + + let (new_tx, mut new_rx) = mpsc::channel(1); + let (new_shutdown_tx, _new_shutdown_rx) = oneshot::channel(); + assert!(registry.register("sb-1".into(), "new-session".into(), new_tx, new_shutdown_tx,)); + + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::SandboxConfig(Box::default()), + ) + .await, + DeliveryDisposition::Enqueued + ); + assert!(old_rx.try_recv().is_err()); + let new_update = new_rx.try_recv().expect("new-session config update"); + let Some(gateway_message::Payload::ConfigUpdate(new_update)) = new_update.payload else { + panic!("expected config update"); + }; + assert_eq!(new_update.component_sequence, 1); + } + + #[tokio::test] + async fn config_router_reports_full_and_closed_queues() { + let registry = Arc::new(SupervisorSessionRegistry::new()); + let router = LocalSupervisorConfigRouter::new(Arc::clone(®istry)); + let (tx, rx) = mpsc::channel(1); + tx.try_send(GatewayMessage::default()).unwrap(); + let (shutdown_tx, _shutdown_rx) = oneshot::channel(); + registry.register("sb-1".into(), "session-1".into(), tx, shutdown_tx); + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::SandboxConfig(Box::default()), + ) + .await, + DeliveryDisposition::QueueFull + ); + + drop(rx); + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::SandboxConfig(Box::default()), + ) + .await, + DeliveryDisposition::SessionClosed + ); + } + + #[tokio::test] + async fn config_router_rejects_oversized_messages() { + let registry = Arc::new(SupervisorSessionRegistry::new()); + let router = LocalSupervisorConfigRouter::new(Arc::clone(®istry)); + let (tx, mut rx) = mpsc::channel(1); + let (shutdown_tx, _shutdown_rx) = oneshot::channel(); + registry.register("sb-1".into(), "session-1".into(), tx, shutdown_tx); + + let snapshot = ProviderEnvironmentSnapshot { + values: vec![ProviderEnvironmentValue { + name: "TOKEN".into(), + value: "x".repeat(MAX_SUPERVISOR_CONFIG_MESSAGE_BYTES), + ..Default::default() + }], + ..Default::default() + }; + assert_eq!( + router + .deliver( + "sb-1", + SupervisorConfigMessage::ProviderEnvironment(snapshot), + ) + .await, + DeliveryDisposition::PayloadTooLarge + ); + assert!(rx.try_recv().is_err()); + } use tokio::io::{AsyncReadExt, AsyncWriteExt}; async fn test_store() -> Arc { diff --git a/crates/openshell-server/tests/common/mod.rs b/crates/openshell-server/tests/common/mod.rs index 414251734d..92029347e6 100644 --- a/crates/openshell-server/tests/common/mod.rs +++ b/crates/openshell-server/tests/common/mod.rs @@ -53,6 +53,13 @@ pub struct TestOpenShell; #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &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 5856acbbda..4327f31456 100644 --- a/crates/openshell-server/tests/supervisor_relay_integration.rs +++ b/crates/openshell-server/tests/supervisor_relay_integration.rs @@ -48,6 +48,13 @@ struct RelayGateway { #[tonic::async_trait] impl OpenShell for RelayGateway { + async fn peer_notify_config_update( + &self, + _request: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("not used by this test server")) + } + async fn peer_report_provider_readiness( &self, _request: tonic::Request, diff --git a/crates/openshell-supervisor-process/src/supervisor_session.rs b/crates/openshell-supervisor-process/src/supervisor_session.rs index 5be01017eb..dd2b63bfc6 100644 --- a/crates/openshell-supervisor-process/src/supervisor_session.rs +++ b/crates/openshell-supervisor-process/src/supervisor_session.rs @@ -21,6 +21,7 @@ use openshell_core::proto::{ RelayOpenResult, ReportMainProcessExitRequest, SupervisorHeartbeat, SupervisorHello, SupervisorMessage, TcpRelayTarget, gateway_message, relay_open, supervisor_message, }; +use openshell_core::proto::{LEGACY_SUPERVISOR_PROTOCOL_REVISION, SUPERVISOR_PROTOCOL_REVISION}; use openshell_isolation_interface::contract::{BoundaryLoopbackConnector, LoopbackTarget}; use openshell_ocsf::{ ActivityId, BaseEventBuilder, ConnectionInfo, Endpoint, EventContext, NetworkActivityBuilder, @@ -413,6 +414,7 @@ async fn run_single_session( payload: Some(supervisor_message::Payload::Hello(SupervisorHello { sandbox_id: config.sandbox_id.clone(), instance_id: config.instance_id.clone(), + protocol_revision: SUPERVISOR_PROTOCOL_REVISION, connection_epoch, supports_provider_readiness: true, })), @@ -446,6 +448,7 @@ async fn run_single_session( .as_ref() .and_then(|value| openshell_core::time::duration_to_std(value).ok()) .map_or(5, |value| value.as_secs().max(5)); + validate_gateway_protocol_revision(accepted.protocol_revision)?; if let Some(updates) = &config.session_id_updates { updates.send_replace(Some(accepted.session_id.clone())); } @@ -456,6 +459,13 @@ async fn run_single_session( u32::try_from(heartbeat_secs).unwrap_or(u32::MAX), ); ocsf_emit!(event); + if accepted.bootstrap.is_some() { + debug!( + sandbox_id = %config.sandbox_id, + session_id = %accepted.session_id, + "supervisor session: ignoring configuration bootstrap while polling remains active" + ); + } config.ready_tx.send_replace(true); // Main loop: receive gateway messages + send heartbeats. @@ -501,6 +511,24 @@ async fn run_single_session( } } +fn validate_gateway_protocol_revision( + gateway_revision: u32, +) -> Result<(), Box> { + match gateway_revision { + SUPERVISOR_PROTOCOL_REVISION => Ok(()), + LEGACY_SUPERVISOR_PROTOCOL_REVISION => { + warn!( + "supervisor session: gateway predates the protocol handshake; upgrade the gateway before pinning newer supervisor images" + ); + Ok(()) + } + other => Err(format!( + "supervisor protocol revision mismatch: supervisor requires {SUPERVISOR_PROTOCOL_REVISION}, gateway offered {other}" + ) + .into()), + } +} + /// Report the canonical process result and wait for durable handling. pub async fn report_main_process_exit( endpoint: &str, @@ -572,6 +600,15 @@ fn handle_gateway_message(msg: &GatewayMessage, context: &GatewayMessageContext< Some(gateway_message::Payload::Heartbeat(_)) => { // Gateway heartbeat — nothing to do. } + Some(gateway_message::Payload::ConfigUpdate(update)) => { + // Stage 1 accepts pushed configuration but leaves polling as the + // only path that changes runtime state. + debug!( + sandbox_id = %context.sandbox_id, + component_sequence = update.component_sequence, + "supervisor session: ignoring configuration update while polling remains active" + ); + } Some(gateway_message::Payload::RelayOpen(open)) => { let channel_id = open.channel_id.clone(); let relay_open = open.clone(); @@ -896,6 +933,19 @@ fn normalize_tcp_target_host(target: &TcpRelayTarget) -> Result mod target_tests { use super::*; + #[test] + fn gateway_protocol_revision_accepts_current_and_legacy_peers() { + assert!(validate_gateway_protocol_revision(SUPERVISOR_PROTOCOL_REVISION).is_ok()); + assert!(validate_gateway_protocol_revision(LEGACY_SUPERVISOR_PROTOCOL_REVISION).is_ok()); + } + + #[test] + fn gateway_protocol_revision_rejects_unknown_peers() { + let error = validate_gateway_protocol_revision(SUPERVISOR_PROTOCOL_REVISION + 1) + .expect_err("version skew must be rejected"); + assert!(error.to_string().contains("revision mismatch")); + } + fn tcp(host: &str, port: u32) -> TcpRelayTarget { TcpRelayTarget { host: host.to_string(), diff --git a/proto/openshell.proto b/proto/openshell.proto index 83ffbe75ad..4e76b4afdc 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -546,9 +546,10 @@ service OpenShell { // // The supervisor opens this stream at startup and keeps it alive for the // sandbox lifetime. The gateway uses it to coordinate relay channels for - // SSH connect, ExecSandbox, and targetable sandbox services. Raw service - // bytes flow over RelayStream calls (separate HTTP/2 streams on the same - // connection), not over this stream. + // SSH connect, ExecSandbox, targetable sandbox services, and configuration + // delivery. Peers must report the same exact protocol_revision during the + // handshake. Raw service bytes flow over RelayStream calls (separate HTTP/2 + // streams on the same connection), not over this stream. rpc ConnectSupervisor(stream SupervisorMessage) returns (stream GatewayMessage) { option (openshell.options.v1.authorization) = { auth_mode: "sandbox" @@ -622,6 +623,15 @@ service OpenShell { }; } + // Best-effort notification to the replica that owns a supervisor session. + // The receiver rebuilds snapshots from authoritative state. + rpc PeerNotifyConfigUpdate(PeerConfigUpdateHintRequest) + returns (PeerConfigUpdateHintResponse) { + option (openshell.options.v1.authorization) = { + auth_mode: "peer" + }; + } + // Watch a sandbox and stream updates. // // This stream can include: @@ -2654,6 +2664,38 @@ message GetSandboxProviderEnvironmentResponse { map files = 10; } +enum ProviderEnvironmentValueClassification { + PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_UNSPECIFIED = 0; + PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_NON_SECRET = 1; + PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_STATIC_CREDENTIAL = 2; +} + +// One environment value and all metadata that shares its key. +message ProviderEnvironmentValue { + reserved 3; + reserved "expires_at_ms"; + string name = 1; + string value = 2 [(openshell.options.v1.secret) = true]; + ProviderEnvironmentValueClassification classification = 4; + StaticCredentialBinding static_credential_binding = 5; + // Absolute expiration time. Absence means no expiry. + google.protobuf.Timestamp expiration_time = 103; +} + +// Complete provider environment state delivered to a supervisor. Dynamic +// credentials are endpoint selectors rather than environment values and stay +// in their own collection. +message ProviderEnvironmentSnapshot { + uint64 provider_env_revision = 1; + repeated ProviderEnvironmentValue values = 2; + map dynamic_credentials = 3; + string provider_attachment_epoch = 4; + string policy_hash = 5; + ProviderReadinessReason readiness_reason = 6; + // Complete desired set of non-secret managed files, keyed by absolute path. + map files = 7; +} + message ExchangeProviderSubjectTokenRequest { // The sandbox ID. Must match the authenticated sandbox principal. string sandbox_id = 1; @@ -2969,6 +3011,9 @@ message GetSandboxLogsResponse { // Supervisor session messages // --------------------------------------------------------------------------- +// These messages form an internal, version-locked deployment protocol between +// the gateway and the supervisor. They are not a public sandbox client API. + // Envelope for supervisor-to-gateway messages on the ConnectSupervisor stream. message SupervisorMessage { oneof payload { @@ -2976,6 +3021,8 @@ message SupervisorMessage { SupervisorHeartbeat heartbeat = 2; RelayOpenResult relay_open_result = 3; RelayClose relay_close = 4; + ConfigUpdateResult config_update_result = 5; + ConfigBootstrapResult config_bootstrap_result = 6; } } @@ -2987,6 +3034,7 @@ message GatewayMessage { GatewayHeartbeat heartbeat = 3; RelayOpen relay_open = 4; RelayClose relay_close = 5; + ConfigUpdate config_update = 6; } } @@ -3001,6 +3049,9 @@ message SupervisorHello { uint64 connection_epoch = 3; // The supervisor can report credential, policy, and launch-environment installation. bool supports_provider_readiness = 4; + // Exact internal stream protocol revision implemented by this supervisor. + // Zero identifies a supervisor built before the handshake existed. + uint32 protocol_revision = 5; } // Gateway accepts the supervisor session. @@ -3009,10 +3060,67 @@ message SessionAccepted { reserved "heartbeat_interval_secs"; // Gateway-assigned session ID for this connection. string session_id = 1; + // Complete gateway-owned configuration. During the staged rollout this may + // be omitted only when the gateway cannot build the projection. + ConfigBootstrap bootstrap = 3; + // Exact internal stream protocol revision implemented by this gateway. + uint32 protocol_revision = 4; // Recommended heartbeat interval. google.protobuf.Duration heartbeat_interval = 102; } +// Complete gateway-owned configuration for a supervisor session. +message ConfigBootstrap { + openshell.sandbox.v1.SandboxConfigSnapshot sandbox_config = 1; + ProviderEnvironmentSnapshot provider_environment = 2; +} + +// A complete replacement snapshot for exactly one configuration component. +message ConfigUpdate { + // Opaque non-empty identifier scoped to the active supervisor session. + string update_id = 1; + // Monotonic within one session and component. Snapshot revisions are + // content identities and must only be compared for equality. + uint64 component_sequence = 2; + oneof component { + openshell.sandbox.v1.SandboxConfigSnapshot sandbox_config = 3; + ProviderEnvironmentSnapshot provider_environment = 4; + } +} + +// Sanitized application failure. Messages must not contain configuration +// payloads, credentials, or provider values. +message ConfigApplyFailure { + string code = 1; + string message = 2; + bool retryable = 3; +} + +message ConfigComponentApplyResult { + ConfigComponent component = 1; + // Revision extracted from the received snapshot. + ConfigSnapshotRevision requested_revision = 2; + // Revision active after this attempt. Omitted when the received snapshot + // was not installed or a local override has no gateway revision. + ConfigSnapshotRevision applied_revision = 3; + ConfigApplyOutcome outcome = 4; + ConfigApplyFailure failure = 5; +} + +// Application result for one ConfigUpdate. +message ConfigUpdateResult { + // Echoes ConfigUpdate.update_id for session-local correlation. + string update_id = 1; + // Echoes ConfigUpdate.component_sequence. + uint64 component_sequence = 2; + ConfigComponentApplyResult result = 3; +} + +// Aggregate application result for the SessionAccepted bootstrap. +message ConfigBootstrapResult { + repeated ConfigComponentApplyResult results = 1; +} + // Gateway rejects the supervisor session. message SessionRejected { // Human-readable rejection reason. @@ -3111,6 +3219,29 @@ message PeerRelayFrame { } } +message PeerConfigSandboxTarget { + string sandbox_id = 1; + // Fences a targeted hint to the session observed by the sending replica. + string session_id = 2; +} + +message PeerConfigUpdateHintRequest { + oneof scope { + PeerConfigSandboxTarget sandbox = 1; + string workspace = 2; + bool all_connected = 3; + } + bool sandbox_config = 4; + bool provider_environment = 5; +} + +message PeerConfigUpdateHintResponse { + // The targeted session moved before the receiving replica accepted the hint. + bool stale_owner = 1; + // The bounded local delivery or fanout queue could not accept the hint. + bool queue_full = 2; +} + // Supervisor reports the result of a relay open request. message RelayOpenResult { // Channel identifier from the RelayOpen request. diff --git a/proto/sandbox.proto b/proto/sandbox.proto index 1d837b7f0e..18d257b2fc 100644 --- a/proto/sandbox.proto +++ b/proto/sandbox.proto @@ -393,13 +393,33 @@ message EffectiveSetting { SettingScope scope = 2; } -// Source used for the policy payload in GetSandboxConfigResponse. +// Source used for a sandbox configuration payload. enum PolicySource { POLICY_SOURCE_UNSPECIFIED = 0; POLICY_SOURCE_SANDBOX = 1; POLICY_SOURCE_GLOBAL = 2; } +// Complete effective sandbox configuration delivered to a supervisor. +message SandboxConfigSnapshot { + SandboxPolicy policy = 1; + uint32 version = 2; + string policy_hash = 3; + map settings = 4; + uint64 config_revision = 5; + PolicySource policy_source = 6; + uint32 global_policy_version = 7; + uint64 provider_env_revision = 8; + repeated SupervisorMiddlewareService supervisor_middleware_services = 9; + string workspace = 10; + string policy_validation_failure_mode = 11; + bool extension_authentication_enabled = 12; + bool configuration_admitted = 13; + string provider_attachment_epoch = 14; + string configuration_instance_id = 15; + string configuration_error = 16; +} + // Response containing effective sandbox settings and policy. message GetSandboxConfigResponse { // The sandbox policy configuration. diff --git a/sdk/go/proto/openshellv1/openshell.pb.go b/sdk/go/proto/openshellv1/openshell.pb.go index 109d2ef454..1167707d5c 100644 --- a/sdk/go/proto/openshellv1/openshell.pb.go +++ b/sdk/go/proto/openshellv1/openshell.pb.go @@ -729,6 +729,55 @@ func (ProviderProfileCategory) EnumDescriptor() ([]byte, []int) { return file_openshell_proto_rawDescGZIP(), []int{10} } +type ProviderEnvironmentValueClassification int32 + +const ( + ProviderEnvironmentValueClassification_PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_UNSPECIFIED ProviderEnvironmentValueClassification = 0 + ProviderEnvironmentValueClassification_PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_NON_SECRET ProviderEnvironmentValueClassification = 1 + ProviderEnvironmentValueClassification_PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_STATIC_CREDENTIAL ProviderEnvironmentValueClassification = 2 +) + +// Enum value maps for ProviderEnvironmentValueClassification. +var ( + ProviderEnvironmentValueClassification_name = map[int32]string{ + 0: "PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_UNSPECIFIED", + 1: "PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_NON_SECRET", + 2: "PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_STATIC_CREDENTIAL", + } + ProviderEnvironmentValueClassification_value = map[string]int32{ + "PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_UNSPECIFIED": 0, + "PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_NON_SECRET": 1, + "PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_STATIC_CREDENTIAL": 2, + } +) + +func (x ProviderEnvironmentValueClassification) Enum() *ProviderEnvironmentValueClassification { + p := new(ProviderEnvironmentValueClassification) + *p = x + return p +} + +func (x ProviderEnvironmentValueClassification) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProviderEnvironmentValueClassification) Descriptor() protoreflect.EnumDescriptor { + return file_openshell_proto_enumTypes[11].Descriptor() +} + +func (ProviderEnvironmentValueClassification) Type() protoreflect.EnumType { + return &file_openshell_proto_enumTypes[11] +} + +func (x ProviderEnvironmentValueClassification) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProviderEnvironmentValueClassification.Descriptor instead. +func (ProviderEnvironmentValueClassification) EnumDescriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{11} +} + type ConfigurationAdmissionState int32 const ( @@ -765,11 +814,11 @@ func (x ConfigurationAdmissionState) String() string { } func (ConfigurationAdmissionState) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[11].Descriptor() + return file_openshell_proto_enumTypes[12].Descriptor() } func (ConfigurationAdmissionState) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[11] + return &file_openshell_proto_enumTypes[12] } func (x ConfigurationAdmissionState) Number() protoreflect.EnumNumber { @@ -778,7 +827,7 @@ func (x ConfigurationAdmissionState) Number() protoreflect.EnumNumber { // Deprecated: Use ConfigurationAdmissionState.Descriptor instead. func (ConfigurationAdmissionState) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{11} + return file_openshell_proto_rawDescGZIP(), []int{12} } // Policy load status. @@ -827,11 +876,11 @@ func (x PolicyStatus) String() string { } func (PolicyStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[12].Descriptor() + return file_openshell_proto_enumTypes[13].Descriptor() } func (PolicyStatus) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[12] + return &file_openshell_proto_enumTypes[13] } func (x PolicyStatus) Number() protoreflect.EnumNumber { @@ -840,7 +889,7 @@ func (x PolicyStatus) Number() protoreflect.EnumNumber { // Deprecated: Use PolicyStatus.Descriptor instead. func (PolicyStatus) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{12} + return file_openshell_proto_rawDescGZIP(), []int{13} } // Service status enum. @@ -880,11 +929,11 @@ func (x ServiceStatus) String() string { } func (ServiceStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[13].Descriptor() + return file_openshell_proto_enumTypes[14].Descriptor() } func (ServiceStatus) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[13] + return &file_openshell_proto_enumTypes[14] } func (x ServiceStatus) Number() protoreflect.EnumNumber { @@ -893,7 +942,7 @@ func (x ServiceStatus) Number() protoreflect.EnumNumber { // Deprecated: Use ServiceStatus.Descriptor instead. func (ServiceStatus) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{13} + return file_openshell_proto_rawDescGZIP(), []int{14} } // Workspace-scoped role for members. @@ -930,11 +979,11 @@ func (x WorkspaceRole) String() string { } func (WorkspaceRole) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[14].Descriptor() + return file_openshell_proto_enumTypes[15].Descriptor() } func (WorkspaceRole) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[14] + return &file_openshell_proto_enumTypes[15] } func (x WorkspaceRole) Number() protoreflect.EnumNumber { @@ -943,7 +992,7 @@ func (x WorkspaceRole) Number() protoreflect.EnumNumber { // Deprecated: Use WorkspaceRole.Descriptor instead. func (WorkspaceRole) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{14} + return file_openshell_proto_rawDescGZIP(), []int{15} } // Stable recovery action for the most recent provider credential refresh @@ -989,11 +1038,11 @@ func (x ProviderCredentialRefreshRecoveryAction) String() string { } func (ProviderCredentialRefreshRecoveryAction) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[15].Descriptor() + return file_openshell_proto_enumTypes[16].Descriptor() } func (ProviderCredentialRefreshRecoveryAction) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[15] + return &file_openshell_proto_enumTypes[16] } func (x ProviderCredentialRefreshRecoveryAction) Number() protoreflect.EnumNumber { @@ -1002,7 +1051,7 @@ func (x ProviderCredentialRefreshRecoveryAction) Number() protoreflect.EnumNumbe // Deprecated: Use ProviderCredentialRefreshRecoveryAction.Descriptor instead. func (ProviderCredentialRefreshRecoveryAction) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{15} + return file_openshell_proto_rawDescGZIP(), []int{16} } // Policy applied when the canonical main process exits outside an intentional @@ -1044,11 +1093,11 @@ func (x SandboxRestartPolicy) String() string { } func (SandboxRestartPolicy) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[16].Descriptor() + return file_openshell_proto_enumTypes[17].Descriptor() } func (SandboxRestartPolicy) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[16] + return &file_openshell_proto_enumTypes[17] } func (x SandboxRestartPolicy) Number() protoreflect.EnumNumber { @@ -1057,7 +1106,7 @@ func (x SandboxRestartPolicy) Number() protoreflect.EnumNumber { // Deprecated: Use SandboxRestartPolicy.Descriptor instead. func (SandboxRestartPolicy) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{16} + return file_openshell_proto_rawDescGZIP(), []int{17} } // Result of a public delete, membership removal, or session revocation. @@ -1107,11 +1156,11 @@ func (x DeletionOutcome) String() string { } func (DeletionOutcome) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[17].Descriptor() + return file_openshell_proto_enumTypes[18].Descriptor() } func (DeletionOutcome) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[17] + return &file_openshell_proto_enumTypes[18] } func (x DeletionOutcome) Number() protoreflect.EnumNumber { @@ -1120,7 +1169,7 @@ func (x DeletionOutcome) Number() protoreflect.EnumNumber { // Deprecated: Use DeletionOutcome.Descriptor instead. func (DeletionOutcome) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{17} + return file_openshell_proto_rawDescGZIP(), []int{18} } // Last observed network result for a configured external tool endpoint. @@ -1181,11 +1230,11 @@ func (x EndpointResult) String() string { } func (EndpointResult) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[18].Descriptor() + return file_openshell_proto_enumTypes[19].Descriptor() } func (EndpointResult) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[18] + return &file_openshell_proto_enumTypes[19] } func (x EndpointResult) Number() protoreflect.EnumNumber { @@ -1194,7 +1243,7 @@ func (x EndpointResult) Number() protoreflect.EnumNumber { // Deprecated: Use EndpointResult.Descriptor instead. func (EndpointResult) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{18} + return file_openshell_proto_rawDescGZIP(), []int{19} } // Controls whether an exposed service receives the request's application @@ -1235,11 +1284,11 @@ func (x ServiceAuthorizationMode) String() string { } func (ServiceAuthorizationMode) Descriptor() protoreflect.EnumDescriptor { - return file_openshell_proto_enumTypes[19].Descriptor() + return file_openshell_proto_enumTypes[20].Descriptor() } func (ServiceAuthorizationMode) Type() protoreflect.EnumType { - return &file_openshell_proto_enumTypes[19] + return &file_openshell_proto_enumTypes[20] } func (x ServiceAuthorizationMode) Number() protoreflect.EnumNumber { @@ -1248,7 +1297,7 @@ func (x ServiceAuthorizationMode) Number() protoreflect.EnumNumber { // Deprecated: Use ServiceAuthorizationMode.Descriptor instead. func (ServiceAuthorizationMode) EnumDescriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{19} + return file_openshell_proto_rawDescGZIP(), []int{20} } // IssueSandboxToken request. Empty body; identity is established by the @@ -11297,6 +11346,180 @@ func (x *GetSandboxProviderEnvironmentResponse) GetFiles() map[string]string { return nil } +// One environment value and all metadata that shares its key. +type ProviderEnvironmentValue struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Classification ProviderEnvironmentValueClassification `protobuf:"varint,4,opt,name=classification,proto3,enum=openshell.v1.ProviderEnvironmentValueClassification" json:"classification,omitempty"` + StaticCredentialBinding *StaticCredentialBinding `protobuf:"bytes,5,opt,name=static_credential_binding,json=staticCredentialBinding,proto3" json:"static_credential_binding,omitempty"` + // Absolute expiration time. Absence means no expiry. + ExpirationTime *timestamppb.Timestamp `protobuf:"bytes,103,opt,name=expiration_time,json=expirationTime,proto3" json:"expiration_time,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProviderEnvironmentValue) Reset() { + *x = ProviderEnvironmentValue{} + mi := &file_openshell_proto_msgTypes[138] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProviderEnvironmentValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProviderEnvironmentValue) ProtoMessage() {} + +func (x *ProviderEnvironmentValue) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[138] + 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 ProviderEnvironmentValue.ProtoReflect.Descriptor instead. +func (*ProviderEnvironmentValue) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{138} +} + +func (x *ProviderEnvironmentValue) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ProviderEnvironmentValue) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ProviderEnvironmentValue) GetClassification() ProviderEnvironmentValueClassification { + if x != nil { + return x.Classification + } + return ProviderEnvironmentValueClassification_PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_UNSPECIFIED +} + +func (x *ProviderEnvironmentValue) GetStaticCredentialBinding() *StaticCredentialBinding { + if x != nil { + return x.StaticCredentialBinding + } + return nil +} + +func (x *ProviderEnvironmentValue) GetExpirationTime() *timestamppb.Timestamp { + if x != nil { + return x.ExpirationTime + } + return nil +} + +// Complete provider environment state delivered to a supervisor. Dynamic +// credentials are endpoint selectors rather than environment values and stay +// in their own collection. +type ProviderEnvironmentSnapshot struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProviderEnvRevision uint64 `protobuf:"varint,1,opt,name=provider_env_revision,json=providerEnvRevision,proto3" json:"provider_env_revision,omitempty"` + Values []*ProviderEnvironmentValue `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"` + DynamicCredentials map[string]*ProviderProfileCredential `protobuf:"bytes,3,rep,name=dynamic_credentials,json=dynamicCredentials,proto3" json:"dynamic_credentials,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ProviderAttachmentEpoch string `protobuf:"bytes,4,opt,name=provider_attachment_epoch,json=providerAttachmentEpoch,proto3" json:"provider_attachment_epoch,omitempty"` + PolicyHash string `protobuf:"bytes,5,opt,name=policy_hash,json=policyHash,proto3" json:"policy_hash,omitempty"` + ReadinessReason ProviderReadinessReason `protobuf:"varint,6,opt,name=readiness_reason,json=readinessReason,proto3,enum=openshell.v1.ProviderReadinessReason" json:"readiness_reason,omitempty"` + // Complete desired set of non-secret managed files, keyed by absolute path. + Files map[string]string `protobuf:"bytes,7,rep,name=files,proto3" json:"files,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProviderEnvironmentSnapshot) Reset() { + *x = ProviderEnvironmentSnapshot{} + mi := &file_openshell_proto_msgTypes[139] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProviderEnvironmentSnapshot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProviderEnvironmentSnapshot) ProtoMessage() {} + +func (x *ProviderEnvironmentSnapshot) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[139] + 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 ProviderEnvironmentSnapshot.ProtoReflect.Descriptor instead. +func (*ProviderEnvironmentSnapshot) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{139} +} + +func (x *ProviderEnvironmentSnapshot) GetProviderEnvRevision() uint64 { + if x != nil { + return x.ProviderEnvRevision + } + return 0 +} + +func (x *ProviderEnvironmentSnapshot) GetValues() []*ProviderEnvironmentValue { + if x != nil { + return x.Values + } + return nil +} + +func (x *ProviderEnvironmentSnapshot) GetDynamicCredentials() map[string]*ProviderProfileCredential { + if x != nil { + return x.DynamicCredentials + } + return nil +} + +func (x *ProviderEnvironmentSnapshot) GetProviderAttachmentEpoch() string { + if x != nil { + return x.ProviderAttachmentEpoch + } + return "" +} + +func (x *ProviderEnvironmentSnapshot) GetPolicyHash() string { + if x != nil { + return x.PolicyHash + } + return "" +} + +func (x *ProviderEnvironmentSnapshot) GetReadinessReason() ProviderReadinessReason { + if x != nil { + return x.ReadinessReason + } + return ProviderReadinessReason_PROVIDER_READINESS_REASON_UNSPECIFIED +} + +func (x *ProviderEnvironmentSnapshot) GetFiles() map[string]string { + if x != nil { + return x.Files + } + return nil +} + type ExchangeProviderSubjectTokenRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // The sandbox ID. Must match the authenticated sandbox principal. @@ -11314,7 +11537,7 @@ type ExchangeProviderSubjectTokenRequest struct { func (x *ExchangeProviderSubjectTokenRequest) Reset() { *x = ExchangeProviderSubjectTokenRequest{} - mi := &file_openshell_proto_msgTypes[138] + mi := &file_openshell_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11326,7 +11549,7 @@ func (x *ExchangeProviderSubjectTokenRequest) String() string { func (*ExchangeProviderSubjectTokenRequest) ProtoMessage() {} func (x *ExchangeProviderSubjectTokenRequest) 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 { @@ -11339,7 +11562,7 @@ func (x *ExchangeProviderSubjectTokenRequest) ProtoReflect() protoreflect.Messag // Deprecated: Use ExchangeProviderSubjectTokenRequest.ProtoReflect.Descriptor instead. func (*ExchangeProviderSubjectTokenRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{138} + return file_openshell_proto_rawDescGZIP(), []int{140} } func (x *ExchangeProviderSubjectTokenRequest) GetSandboxId() string { @@ -11381,7 +11604,7 @@ type ExchangeProviderSubjectTokenResponse struct { func (x *ExchangeProviderSubjectTokenResponse) Reset() { *x = ExchangeProviderSubjectTokenResponse{} - mi := &file_openshell_proto_msgTypes[139] + mi := &file_openshell_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11393,7 +11616,7 @@ func (x *ExchangeProviderSubjectTokenResponse) String() string { func (*ExchangeProviderSubjectTokenResponse) ProtoMessage() {} func (x *ExchangeProviderSubjectTokenResponse) 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 { @@ -11406,7 +11629,7 @@ func (x *ExchangeProviderSubjectTokenResponse) ProtoReflect() protoreflect.Messa // Deprecated: Use ExchangeProviderSubjectTokenResponse.ProtoReflect.Descriptor instead. func (*ExchangeProviderSubjectTokenResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{139} + return file_openshell_proto_rawDescGZIP(), []int{141} } func (x *ExchangeProviderSubjectTokenResponse) GetAccessToken() string { @@ -11479,7 +11702,7 @@ type UpdateConfigRequest struct { func (x *UpdateConfigRequest) Reset() { *x = UpdateConfigRequest{} - mi := &file_openshell_proto_msgTypes[140] + mi := &file_openshell_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11491,7 +11714,7 @@ func (x *UpdateConfigRequest) String() string { func (*UpdateConfigRequest) ProtoMessage() {} func (x *UpdateConfigRequest) 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 { @@ -11504,7 +11727,7 @@ func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateConfigRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{140} + return file_openshell_proto_rawDescGZIP(), []int{142} } func (x *UpdateConfigRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -11601,7 +11824,7 @@ type PolicyMergeOperation struct { func (x *PolicyMergeOperation) Reset() { *x = PolicyMergeOperation{} - mi := &file_openshell_proto_msgTypes[141] + mi := &file_openshell_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11613,7 +11836,7 @@ func (x *PolicyMergeOperation) String() string { func (*PolicyMergeOperation) ProtoMessage() {} func (x *PolicyMergeOperation) 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 { @@ -11626,7 +11849,7 @@ func (x *PolicyMergeOperation) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyMergeOperation.ProtoReflect.Descriptor instead. func (*PolicyMergeOperation) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{141} + return file_openshell_proto_rawDescGZIP(), []int{143} } func (x *PolicyMergeOperation) GetOperation() isPolicyMergeOperation_Operation { @@ -11740,7 +11963,7 @@ type AddNetworkRule struct { func (x *AddNetworkRule) Reset() { *x = AddNetworkRule{} - mi := &file_openshell_proto_msgTypes[142] + mi := &file_openshell_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11752,7 +11975,7 @@ func (x *AddNetworkRule) String() string { func (*AddNetworkRule) ProtoMessage() {} func (x *AddNetworkRule) 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 { @@ -11765,7 +11988,7 @@ func (x *AddNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use AddNetworkRule.ProtoReflect.Descriptor instead. func (*AddNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{142} + return file_openshell_proto_rawDescGZIP(), []int{144} } func (x *AddNetworkRule) GetRuleName() string { @@ -11793,7 +12016,7 @@ type RemoveNetworkEndpoint struct { func (x *RemoveNetworkEndpoint) Reset() { *x = RemoveNetworkEndpoint{} - mi := &file_openshell_proto_msgTypes[143] + mi := &file_openshell_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11805,7 +12028,7 @@ func (x *RemoveNetworkEndpoint) String() string { func (*RemoveNetworkEndpoint) ProtoMessage() {} func (x *RemoveNetworkEndpoint) 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 { @@ -11818,7 +12041,7 @@ func (x *RemoveNetworkEndpoint) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkEndpoint.ProtoReflect.Descriptor instead. func (*RemoveNetworkEndpoint) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{143} + return file_openshell_proto_rawDescGZIP(), []int{145} } func (x *RemoveNetworkEndpoint) GetRuleName() string { @@ -11851,7 +12074,7 @@ type RemoveNetworkRule struct { func (x *RemoveNetworkRule) Reset() { *x = RemoveNetworkRule{} - mi := &file_openshell_proto_msgTypes[144] + mi := &file_openshell_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11863,7 +12086,7 @@ func (x *RemoveNetworkRule) String() string { func (*RemoveNetworkRule) ProtoMessage() {} func (x *RemoveNetworkRule) 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 { @@ -11876,7 +12099,7 @@ func (x *RemoveNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkRule.ProtoReflect.Descriptor instead. func (*RemoveNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{144} + return file_openshell_proto_rawDescGZIP(), []int{146} } func (x *RemoveNetworkRule) GetRuleName() string { @@ -11905,7 +12128,7 @@ type L7RuleTarget struct { func (x *L7RuleTarget) Reset() { *x = L7RuleTarget{} - mi := &file_openshell_proto_msgTypes[145] + mi := &file_openshell_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11917,7 +12140,7 @@ func (x *L7RuleTarget) String() string { func (*L7RuleTarget) ProtoMessage() {} func (x *L7RuleTarget) 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 { @@ -11930,7 +12153,7 @@ func (x *L7RuleTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use L7RuleTarget.ProtoReflect.Descriptor instead. func (*L7RuleTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{145} + return file_openshell_proto_rawDescGZIP(), []int{147} } func (x *L7RuleTarget) GetRuleName() string { @@ -11985,7 +12208,7 @@ type AddDenyRules struct { func (x *AddDenyRules) Reset() { *x = AddDenyRules{} - mi := &file_openshell_proto_msgTypes[146] + mi := &file_openshell_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11997,7 +12220,7 @@ func (x *AddDenyRules) String() string { func (*AddDenyRules) ProtoMessage() {} func (x *AddDenyRules) 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 { @@ -12010,7 +12233,7 @@ func (x *AddDenyRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddDenyRules.ProtoReflect.Descriptor instead. func (*AddDenyRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{146} + return file_openshell_proto_rawDescGZIP(), []int{148} } func (x *AddDenyRules) GetDenyRules() []*sandboxv1.L7DenyRule { @@ -12037,7 +12260,7 @@ type AddAllowRules struct { func (x *AddAllowRules) Reset() { *x = AddAllowRules{} - mi := &file_openshell_proto_msgTypes[147] + mi := &file_openshell_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12049,7 +12272,7 @@ func (x *AddAllowRules) String() string { func (*AddAllowRules) ProtoMessage() {} func (x *AddAllowRules) 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 { @@ -12062,7 +12285,7 @@ func (x *AddAllowRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddAllowRules.ProtoReflect.Descriptor instead. func (*AddAllowRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{147} + return file_openshell_proto_rawDescGZIP(), []int{149} } func (x *AddAllowRules) GetRules() []*sandboxv1.L7Rule { @@ -12089,7 +12312,7 @@ type RemoveNetworkBinary struct { func (x *RemoveNetworkBinary) Reset() { *x = RemoveNetworkBinary{} - mi := &file_openshell_proto_msgTypes[148] + mi := &file_openshell_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12101,7 +12324,7 @@ func (x *RemoveNetworkBinary) String() string { func (*RemoveNetworkBinary) ProtoMessage() {} func (x *RemoveNetworkBinary) 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 { @@ -12114,7 +12337,7 @@ func (x *RemoveNetworkBinary) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkBinary.ProtoReflect.Descriptor instead. func (*RemoveNetworkBinary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{148} + return file_openshell_proto_rawDescGZIP(), []int{150} } func (x *RemoveNetworkBinary) GetRuleName() string { @@ -12150,7 +12373,7 @@ type UpdateConfigResponse struct { func (x *UpdateConfigResponse) Reset() { *x = UpdateConfigResponse{} - mi := &file_openshell_proto_msgTypes[149] + mi := &file_openshell_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12162,7 +12385,7 @@ func (x *UpdateConfigResponse) String() string { func (*UpdateConfigResponse) ProtoMessage() {} func (x *UpdateConfigResponse) 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 { @@ -12175,7 +12398,7 @@ func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateConfigResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{149} + return file_openshell_proto_rawDescGZIP(), []int{151} } func (x *UpdateConfigResponse) GetVersion() uint32 { @@ -12229,7 +12452,7 @@ type GetSandboxPolicyStatusRequest struct { func (x *GetSandboxPolicyStatusRequest) Reset() { *x = GetSandboxPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[150] + mi := &file_openshell_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12241,7 +12464,7 @@ func (x *GetSandboxPolicyStatusRequest) String() string { func (*GetSandboxPolicyStatusRequest) ProtoMessage() {} func (x *GetSandboxPolicyStatusRequest) 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 { @@ -12254,7 +12477,7 @@ func (x *GetSandboxPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{150} + return file_openshell_proto_rawDescGZIP(), []int{152} } func (x *GetSandboxPolicyStatusRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -12298,7 +12521,7 @@ type GetSandboxPolicyStatusResponse struct { func (x *GetSandboxPolicyStatusResponse) Reset() { *x = GetSandboxPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[151] + mi := &file_openshell_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12310,7 +12533,7 @@ func (x *GetSandboxPolicyStatusResponse) String() string { func (*GetSandboxPolicyStatusResponse) ProtoMessage() {} func (x *GetSandboxPolicyStatusResponse) 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 { @@ -12323,7 +12546,7 @@ func (x *GetSandboxPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{151} + return file_openshell_proto_rawDescGZIP(), []int{153} } func (x *GetSandboxPolicyStatusResponse) GetRevision() *SandboxPolicyRevision { @@ -12360,7 +12583,7 @@ type ListSandboxPoliciesRequest struct { func (x *ListSandboxPoliciesRequest) Reset() { *x = ListSandboxPoliciesRequest{} - mi := &file_openshell_proto_msgTypes[152] + mi := &file_openshell_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12372,7 +12595,7 @@ func (x *ListSandboxPoliciesRequest) String() string { func (*ListSandboxPoliciesRequest) ProtoMessage() {} func (x *ListSandboxPoliciesRequest) 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 { @@ -12385,7 +12608,7 @@ func (x *ListSandboxPoliciesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesRequest.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{152} + return file_openshell_proto_rawDescGZIP(), []int{154} } func (x *ListSandboxPoliciesRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -12437,7 +12660,7 @@ type ListSandboxPoliciesResponse struct { func (x *ListSandboxPoliciesResponse) Reset() { *x = ListSandboxPoliciesResponse{} - mi := &file_openshell_proto_msgTypes[153] + mi := &file_openshell_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12449,7 +12672,7 @@ func (x *ListSandboxPoliciesResponse) String() string { func (*ListSandboxPoliciesResponse) ProtoMessage() {} func (x *ListSandboxPoliciesResponse) 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 { @@ -12462,7 +12685,7 @@ func (x *ListSandboxPoliciesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesResponse.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{153} + return file_openshell_proto_rawDescGZIP(), []int{155} } func (x *ListSandboxPoliciesResponse) GetRevisions() []*SandboxPolicyRevision { @@ -12496,7 +12719,7 @@ type ReportPolicyStatusRequest struct { func (x *ReportPolicyStatusRequest) Reset() { *x = ReportPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[154] + mi := &file_openshell_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12508,7 +12731,7 @@ func (x *ReportPolicyStatusRequest) String() string { func (*ReportPolicyStatusRequest) ProtoMessage() {} func (x *ReportPolicyStatusRequest) 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 { @@ -12521,7 +12744,7 @@ func (x *ReportPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{154} + return file_openshell_proto_rawDescGZIP(), []int{156} } func (x *ReportPolicyStatusRequest) GetSandboxId() string { @@ -12561,7 +12784,7 @@ type ReportPolicyStatusResponse struct { func (x *ReportPolicyStatusResponse) Reset() { *x = ReportPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[155] + mi := &file_openshell_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12573,7 +12796,7 @@ func (x *ReportPolicyStatusResponse) String() string { func (*ReportPolicyStatusResponse) ProtoMessage() {} func (x *ReportPolicyStatusResponse) 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 { @@ -12586,7 +12809,7 @@ func (x *ReportPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{155} + return file_openshell_proto_rawDescGZIP(), []int{157} } type SandboxConfigurationAdmission struct { @@ -12604,7 +12827,7 @@ type SandboxConfigurationAdmission struct { func (x *SandboxConfigurationAdmission) Reset() { *x = SandboxConfigurationAdmission{} - mi := &file_openshell_proto_msgTypes[156] + mi := &file_openshell_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12616,7 +12839,7 @@ func (x *SandboxConfigurationAdmission) String() string { func (*SandboxConfigurationAdmission) ProtoMessage() {} func (x *SandboxConfigurationAdmission) 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 { @@ -12629,7 +12852,7 @@ func (x *SandboxConfigurationAdmission) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxConfigurationAdmission.ProtoReflect.Descriptor instead. func (*SandboxConfigurationAdmission) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{156} + return file_openshell_proto_rawDescGZIP(), []int{158} } func (x *SandboxConfigurationAdmission) GetInstanceId() string { @@ -12693,7 +12916,7 @@ type ReportSandboxConfigurationRequest struct { func (x *ReportSandboxConfigurationRequest) Reset() { *x = ReportSandboxConfigurationRequest{} - mi := &file_openshell_proto_msgTypes[157] + mi := &file_openshell_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12705,7 +12928,7 @@ func (x *ReportSandboxConfigurationRequest) String() string { func (*ReportSandboxConfigurationRequest) ProtoMessage() {} func (x *ReportSandboxConfigurationRequest) 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 { @@ -12718,7 +12941,7 @@ func (x *ReportSandboxConfigurationRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ReportSandboxConfigurationRequest.ProtoReflect.Descriptor instead. func (*ReportSandboxConfigurationRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{157} + return file_openshell_proto_rawDescGZIP(), []int{159} } func (x *ReportSandboxConfigurationRequest) GetSandboxId() string { @@ -12750,7 +12973,7 @@ type ReportSandboxConfigurationResponse struct { func (x *ReportSandboxConfigurationResponse) Reset() { *x = ReportSandboxConfigurationResponse{} - mi := &file_openshell_proto_msgTypes[158] + mi := &file_openshell_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12762,7 +12985,7 @@ func (x *ReportSandboxConfigurationResponse) String() string { func (*ReportSandboxConfigurationResponse) ProtoMessage() {} func (x *ReportSandboxConfigurationResponse) 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 { @@ -12775,7 +12998,7 @@ func (x *ReportSandboxConfigurationResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ReportSandboxConfigurationResponse.ProtoReflect.Descriptor instead. func (*ReportSandboxConfigurationResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{158} + return file_openshell_proto_rawDescGZIP(), []int{160} } // A versioned policy revision with metadata. @@ -12808,7 +13031,7 @@ type SandboxPolicyRevision struct { func (x *SandboxPolicyRevision) Reset() { *x = SandboxPolicyRevision{} - mi := &file_openshell_proto_msgTypes[159] + mi := &file_openshell_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12820,7 +13043,7 @@ func (x *SandboxPolicyRevision) String() string { func (*SandboxPolicyRevision) ProtoMessage() {} func (x *SandboxPolicyRevision) 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 { @@ -12833,7 +13056,7 @@ func (x *SandboxPolicyRevision) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxPolicyRevision.ProtoReflect.Descriptor instead. func (*SandboxPolicyRevision) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{159} + return file_openshell_proto_rawDescGZIP(), []int{161} } func (x *SandboxPolicyRevision) GetVersion() uint32 { @@ -12913,7 +13136,7 @@ type GetSandboxLogsRequest struct { func (x *GetSandboxLogsRequest) Reset() { *x = GetSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[160] + mi := &file_openshell_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12925,7 +13148,7 @@ func (x *GetSandboxLogsRequest) String() string { func (*GetSandboxLogsRequest) ProtoMessage() {} func (x *GetSandboxLogsRequest) 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 { @@ -12938,7 +13161,7 @@ func (x *GetSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*GetSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{160} + return file_openshell_proto_rawDescGZIP(), []int{162} } func (x *GetSandboxLogsRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -12996,7 +13219,7 @@ type PushSandboxLogsRequest struct { func (x *PushSandboxLogsRequest) Reset() { *x = PushSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[161] + mi := &file_openshell_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13008,7 +13231,7 @@ func (x *PushSandboxLogsRequest) String() string { func (*PushSandboxLogsRequest) ProtoMessage() {} func (x *PushSandboxLogsRequest) 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 { @@ -13021,7 +13244,7 @@ func (x *PushSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*PushSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{161} + return file_openshell_proto_rawDescGZIP(), []int{163} } func (x *PushSandboxLogsRequest) GetSandboxId() string { @@ -13047,7 +13270,7 @@ type PushSandboxLogsResponse struct { func (x *PushSandboxLogsResponse) Reset() { *x = PushSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[162] + mi := &file_openshell_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13059,7 +13282,7 @@ func (x *PushSandboxLogsResponse) String() string { func (*PushSandboxLogsResponse) ProtoMessage() {} func (x *PushSandboxLogsResponse) 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 { @@ -13072,7 +13295,7 @@ func (x *PushSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*PushSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{162} + return file_openshell_proto_rawDescGZIP(), []int{164} } // Get sandbox logs response. @@ -13088,7 +13311,7 @@ type GetSandboxLogsResponse struct { func (x *GetSandboxLogsResponse) Reset() { *x = GetSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[163] + mi := &file_openshell_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13100,7 +13323,7 @@ func (x *GetSandboxLogsResponse) String() string { func (*GetSandboxLogsResponse) ProtoMessage() {} func (x *GetSandboxLogsResponse) 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 { @@ -13113,7 +13336,7 @@ func (x *GetSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*GetSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{163} + return file_openshell_proto_rawDescGZIP(), []int{165} } func (x *GetSandboxLogsResponse) GetLogs() []*SandboxLogLine { @@ -13139,6 +13362,8 @@ type SupervisorMessage struct { // *SupervisorMessage_Heartbeat // *SupervisorMessage_RelayOpenResult // *SupervisorMessage_RelayClose + // *SupervisorMessage_ConfigUpdateResult + // *SupervisorMessage_ConfigBootstrapResult Payload isSupervisorMessage_Payload `protobuf_oneof:"payload"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -13146,7 +13371,7 @@ type SupervisorMessage struct { func (x *SupervisorMessage) Reset() { *x = SupervisorMessage{} - mi := &file_openshell_proto_msgTypes[164] + mi := &file_openshell_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13158,7 +13383,7 @@ func (x *SupervisorMessage) String() string { func (*SupervisorMessage) ProtoMessage() {} func (x *SupervisorMessage) 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 { @@ -13171,7 +13396,7 @@ func (x *SupervisorMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorMessage.ProtoReflect.Descriptor instead. func (*SupervisorMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{164} + return file_openshell_proto_rawDescGZIP(), []int{166} } func (x *SupervisorMessage) GetPayload() isSupervisorMessage_Payload { @@ -13217,6 +13442,24 @@ func (x *SupervisorMessage) GetRelayClose() *RelayClose { return nil } +func (x *SupervisorMessage) GetConfigUpdateResult() *ConfigUpdateResult { + if x != nil { + if x, ok := x.Payload.(*SupervisorMessage_ConfigUpdateResult); ok { + return x.ConfigUpdateResult + } + } + return nil +} + +func (x *SupervisorMessage) GetConfigBootstrapResult() *ConfigBootstrapResult { + if x != nil { + if x, ok := x.Payload.(*SupervisorMessage_ConfigBootstrapResult); ok { + return x.ConfigBootstrapResult + } + } + return nil +} + type isSupervisorMessage_Payload interface { isSupervisorMessage_Payload() } @@ -13237,6 +13480,14 @@ type SupervisorMessage_RelayClose struct { RelayClose *RelayClose `protobuf:"bytes,4,opt,name=relay_close,json=relayClose,proto3,oneof"` } +type SupervisorMessage_ConfigUpdateResult struct { + ConfigUpdateResult *ConfigUpdateResult `protobuf:"bytes,5,opt,name=config_update_result,json=configUpdateResult,proto3,oneof"` +} + +type SupervisorMessage_ConfigBootstrapResult struct { + ConfigBootstrapResult *ConfigBootstrapResult `protobuf:"bytes,6,opt,name=config_bootstrap_result,json=configBootstrapResult,proto3,oneof"` +} + func (*SupervisorMessage_Hello) isSupervisorMessage_Payload() {} func (*SupervisorMessage_Heartbeat) isSupervisorMessage_Payload() {} @@ -13245,6 +13496,10 @@ func (*SupervisorMessage_RelayOpenResult) isSupervisorMessage_Payload() {} func (*SupervisorMessage_RelayClose) isSupervisorMessage_Payload() {} +func (*SupervisorMessage_ConfigUpdateResult) isSupervisorMessage_Payload() {} + +func (*SupervisorMessage_ConfigBootstrapResult) isSupervisorMessage_Payload() {} + // Envelope for gateway-to-supervisor messages on the ConnectSupervisor stream. type GatewayMessage struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -13255,6 +13510,7 @@ type GatewayMessage struct { // *GatewayMessage_Heartbeat // *GatewayMessage_RelayOpen // *GatewayMessage_RelayClose + // *GatewayMessage_ConfigUpdate Payload isGatewayMessage_Payload `protobuf_oneof:"payload"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -13262,7 +13518,7 @@ type GatewayMessage struct { func (x *GatewayMessage) Reset() { *x = GatewayMessage{} - mi := &file_openshell_proto_msgTypes[165] + mi := &file_openshell_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13274,7 +13530,7 @@ func (x *GatewayMessage) String() string { func (*GatewayMessage) ProtoMessage() {} func (x *GatewayMessage) 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 { @@ -13287,7 +13543,7 @@ func (x *GatewayMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use GatewayMessage.ProtoReflect.Descriptor instead. func (*GatewayMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{165} + return file_openshell_proto_rawDescGZIP(), []int{167} } func (x *GatewayMessage) GetPayload() isGatewayMessage_Payload { @@ -13342,6 +13598,15 @@ func (x *GatewayMessage) GetRelayClose() *RelayClose { return nil } +func (x *GatewayMessage) GetConfigUpdate() *ConfigUpdate { + if x != nil { + if x, ok := x.Payload.(*GatewayMessage_ConfigUpdate); ok { + return x.ConfigUpdate + } + } + return nil +} + type isGatewayMessage_Payload interface { isGatewayMessage_Payload() } @@ -13366,6 +13631,10 @@ type GatewayMessage_RelayClose struct { RelayClose *RelayClose `protobuf:"bytes,5,opt,name=relay_close,json=relayClose,proto3,oneof"` } +type GatewayMessage_ConfigUpdate struct { + ConfigUpdate *ConfigUpdate `protobuf:"bytes,6,opt,name=config_update,json=configUpdate,proto3,oneof"` +} + func (*GatewayMessage_SessionAccepted) isGatewayMessage_Payload() {} func (*GatewayMessage_SessionRejected) isGatewayMessage_Payload() {} @@ -13376,6 +13645,8 @@ func (*GatewayMessage_RelayOpen) isGatewayMessage_Payload() {} func (*GatewayMessage_RelayClose) isGatewayMessage_Payload() {} +func (*GatewayMessage_ConfigUpdate) isGatewayMessage_Payload() {} + // Supervisor identifies itself and the sandbox it manages. type SupervisorHello struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -13388,13 +13659,16 @@ type SupervisorHello struct { ConnectionEpoch uint64 `protobuf:"varint,3,opt,name=connection_epoch,json=connectionEpoch,proto3" json:"connection_epoch,omitempty"` // The supervisor can report credential, policy, and launch-environment installation. SupportsProviderReadiness bool `protobuf:"varint,4,opt,name=supports_provider_readiness,json=supportsProviderReadiness,proto3" json:"supports_provider_readiness,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Exact internal stream protocol revision implemented by this supervisor. + // Zero identifies a supervisor built before the handshake existed. + ProtocolRevision uint32 `protobuf:"varint,5,opt,name=protocol_revision,json=protocolRevision,proto3" json:"protocol_revision,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SupervisorHello) Reset() { *x = SupervisorHello{} - mi := &file_openshell_proto_msgTypes[166] + mi := &file_openshell_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13406,7 +13680,7 @@ func (x *SupervisorHello) String() string { func (*SupervisorHello) ProtoMessage() {} func (x *SupervisorHello) 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 { @@ -13419,7 +13693,7 @@ func (x *SupervisorHello) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorHello.ProtoReflect.Descriptor instead. func (*SupervisorHello) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{166} + return file_openshell_proto_rawDescGZIP(), []int{168} } func (x *SupervisorHello) GetSandboxId() string { @@ -13450,11 +13724,23 @@ func (x *SupervisorHello) GetSupportsProviderReadiness() bool { return false } +func (x *SupervisorHello) GetProtocolRevision() uint32 { + if x != nil { + return x.ProtocolRevision + } + return 0 +} + // Gateway accepts the supervisor session. type SessionAccepted struct { state protoimpl.MessageState `protogen:"open.v1"` // Gateway-assigned session ID for this connection. SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // Complete gateway-owned configuration. During the staged rollout this may + // be omitted only when the gateway cannot build the projection. + Bootstrap *ConfigBootstrap `protobuf:"bytes,3,opt,name=bootstrap,proto3" json:"bootstrap,omitempty"` + // Exact internal stream protocol revision implemented by this gateway. + ProtocolRevision uint32 `protobuf:"varint,4,opt,name=protocol_revision,json=protocolRevision,proto3" json:"protocol_revision,omitempty"` // Recommended heartbeat interval. HeartbeatInterval *durationpb.Duration `protobuf:"bytes,102,opt,name=heartbeat_interval,json=heartbeatInterval,proto3" json:"heartbeat_interval,omitempty"` unknownFields protoimpl.UnknownFields @@ -13463,7 +13749,7 @@ type SessionAccepted struct { func (x *SessionAccepted) Reset() { *x = SessionAccepted{} - mi := &file_openshell_proto_msgTypes[167] + mi := &file_openshell_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13475,7 +13761,7 @@ func (x *SessionAccepted) String() string { func (*SessionAccepted) ProtoMessage() {} func (x *SessionAccepted) 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 { @@ -13488,7 +13774,7 @@ func (x *SessionAccepted) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionAccepted.ProtoReflect.Descriptor instead. func (*SessionAccepted) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{167} + return file_openshell_proto_rawDescGZIP(), []int{169} } func (x *SessionAccepted) GetSessionId() string { @@ -13498,6 +13784,20 @@ func (x *SessionAccepted) GetSessionId() string { return "" } +func (x *SessionAccepted) GetBootstrap() *ConfigBootstrap { + if x != nil { + return x.Bootstrap + } + return nil +} + +func (x *SessionAccepted) GetProtocolRevision() uint32 { + if x != nil { + return x.ProtocolRevision + } + return 0 +} + func (x *SessionAccepted) GetHeartbeatInterval() *durationpb.Duration { if x != nil { return x.HeartbeatInterval @@ -13505,30 +13805,30 @@ func (x *SessionAccepted) GetHeartbeatInterval() *durationpb.Duration { return nil } -// Gateway rejects the supervisor session. -type SessionRejected struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Human-readable rejection reason. - Reason string `protobuf:"bytes,1,opt,name=reason,proto3" json:"reason,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +// Complete gateway-owned configuration for a supervisor session. +type ConfigBootstrap struct { + state protoimpl.MessageState `protogen:"open.v1"` + SandboxConfig *sandboxv1.SandboxConfigSnapshot `protobuf:"bytes,1,opt,name=sandbox_config,json=sandboxConfig,proto3" json:"sandbox_config,omitempty"` + ProviderEnvironment *ProviderEnvironmentSnapshot `protobuf:"bytes,2,opt,name=provider_environment,json=providerEnvironment,proto3" json:"provider_environment,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *SessionRejected) Reset() { - *x = SessionRejected{} - mi := &file_openshell_proto_msgTypes[168] +func (x *ConfigBootstrap) Reset() { + *x = ConfigBootstrap{} + mi := &file_openshell_proto_msgTypes[170] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *SessionRejected) String() string { +func (x *ConfigBootstrap) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SessionRejected) ProtoMessage() {} +func (*ConfigBootstrap) ProtoMessage() {} -func (x *SessionRejected) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[168] +func (x *ConfigBootstrap) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[170] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13539,40 +13839,57 @@ func (x *SessionRejected) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SessionRejected.ProtoReflect.Descriptor instead. -func (*SessionRejected) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{168} +// Deprecated: Use ConfigBootstrap.ProtoReflect.Descriptor instead. +func (*ConfigBootstrap) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{170} } -func (x *SessionRejected) GetReason() string { +func (x *ConfigBootstrap) GetSandboxConfig() *sandboxv1.SandboxConfigSnapshot { if x != nil { - return x.Reason + return x.SandboxConfig } - return "" + return nil } -// Supervisor heartbeat. -type SupervisorHeartbeat struct { - state protoimpl.MessageState `protogen:"open.v1"` +func (x *ConfigBootstrap) GetProviderEnvironment() *ProviderEnvironmentSnapshot { + if x != nil { + return x.ProviderEnvironment + } + return nil +} + +// A complete replacement snapshot for exactly one configuration component. +type ConfigUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Opaque non-empty identifier scoped to the active supervisor session. + UpdateId string `protobuf:"bytes,1,opt,name=update_id,json=updateId,proto3" json:"update_id,omitempty"` + // Monotonic within one session and component. Snapshot revisions are + // content identities and must only be compared for equality. + ComponentSequence uint64 `protobuf:"varint,2,opt,name=component_sequence,json=componentSequence,proto3" json:"component_sequence,omitempty"` + // Types that are valid to be assigned to Component: + // + // *ConfigUpdate_SandboxConfig + // *ConfigUpdate_ProviderEnvironment + Component isConfigUpdate_Component `protobuf_oneof:"component"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *SupervisorHeartbeat) Reset() { - *x = SupervisorHeartbeat{} - mi := &file_openshell_proto_msgTypes[169] +func (x *ConfigUpdate) Reset() { + *x = ConfigUpdate{} + mi := &file_openshell_proto_msgTypes[171] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *SupervisorHeartbeat) String() string { +func (x *ConfigUpdate) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SupervisorHeartbeat) ProtoMessage() {} +func (*ConfigUpdate) ProtoMessage() {} -func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[169] +func (x *ConfigUpdate) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[171] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13583,46 +13900,433 @@ func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SupervisorHeartbeat.ProtoReflect.Descriptor instead. -func (*SupervisorHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{169} +// Deprecated: Use ConfigUpdate.ProtoReflect.Descriptor instead. +func (*ConfigUpdate) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{171} } -// Gateway heartbeat. -type GatewayHeartbeat struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +func (x *ConfigUpdate) GetUpdateId() string { + if x != nil { + return x.UpdateId + } + return "" } -func (x *GatewayHeartbeat) Reset() { - *x = GatewayHeartbeat{} - mi := &file_openshell_proto_msgTypes[170] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *ConfigUpdate) GetComponentSequence() uint64 { + if x != nil { + return x.ComponentSequence + } + return 0 } -func (x *GatewayHeartbeat) String() string { - return protoimpl.X.MessageStringOf(x) +func (x *ConfigUpdate) GetComponent() isConfigUpdate_Component { + if x != nil { + return x.Component + } + return nil } -func (*GatewayHeartbeat) ProtoMessage() {} - -func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[170] +func (x *ConfigUpdate) GetSandboxConfig() *sandboxv1.SandboxConfigSnapshot { if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) + if x, ok := x.Component.(*ConfigUpdate_SandboxConfig); ok { + return x.SandboxConfig } - return ms } - return mi.MessageOf(x) + return nil } -// Deprecated: Use GatewayHeartbeat.ProtoReflect.Descriptor instead. -func (*GatewayHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{170} +func (x *ConfigUpdate) GetProviderEnvironment() *ProviderEnvironmentSnapshot { + if x != nil { + if x, ok := x.Component.(*ConfigUpdate_ProviderEnvironment); ok { + return x.ProviderEnvironment + } + } + return nil +} + +type isConfigUpdate_Component interface { + isConfigUpdate_Component() +} + +type ConfigUpdate_SandboxConfig struct { + SandboxConfig *sandboxv1.SandboxConfigSnapshot `protobuf:"bytes,3,opt,name=sandbox_config,json=sandboxConfig,proto3,oneof"` +} + +type ConfigUpdate_ProviderEnvironment struct { + ProviderEnvironment *ProviderEnvironmentSnapshot `protobuf:"bytes,4,opt,name=provider_environment,json=providerEnvironment,proto3,oneof"` +} + +func (*ConfigUpdate_SandboxConfig) isConfigUpdate_Component() {} + +func (*ConfigUpdate_ProviderEnvironment) isConfigUpdate_Component() {} + +// Sanitized application failure. Messages must not contain configuration +// payloads, credentials, or provider values. +type ConfigApplyFailure struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Retryable bool `protobuf:"varint,3,opt,name=retryable,proto3" json:"retryable,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigApplyFailure) Reset() { + *x = ConfigApplyFailure{} + mi := &file_openshell_proto_msgTypes[172] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigApplyFailure) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigApplyFailure) ProtoMessage() {} + +func (x *ConfigApplyFailure) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[172] + 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 ConfigApplyFailure.ProtoReflect.Descriptor instead. +func (*ConfigApplyFailure) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{172} +} + +func (x *ConfigApplyFailure) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *ConfigApplyFailure) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ConfigApplyFailure) GetRetryable() bool { + if x != nil { + return x.Retryable + } + return false +} + +type ConfigComponentApplyResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + Component ConfigComponent `protobuf:"varint,1,opt,name=component,proto3,enum=openshell.v1.ConfigComponent" json:"component,omitempty"` + // Revision extracted from the received snapshot. + RequestedRevision *ConfigSnapshotRevision `protobuf:"bytes,2,opt,name=requested_revision,json=requestedRevision,proto3" json:"requested_revision,omitempty"` + // Revision active after this attempt. Omitted when the received snapshot + // was not installed or a local override has no gateway revision. + AppliedRevision *ConfigSnapshotRevision `protobuf:"bytes,3,opt,name=applied_revision,json=appliedRevision,proto3" json:"applied_revision,omitempty"` + Outcome ConfigApplyOutcome `protobuf:"varint,4,opt,name=outcome,proto3,enum=openshell.v1.ConfigApplyOutcome" json:"outcome,omitempty"` + Failure *ConfigApplyFailure `protobuf:"bytes,5,opt,name=failure,proto3" json:"failure,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigComponentApplyResult) Reset() { + *x = ConfigComponentApplyResult{} + mi := &file_openshell_proto_msgTypes[173] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigComponentApplyResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigComponentApplyResult) ProtoMessage() {} + +func (x *ConfigComponentApplyResult) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[173] + 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 ConfigComponentApplyResult.ProtoReflect.Descriptor instead. +func (*ConfigComponentApplyResult) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{173} +} + +func (x *ConfigComponentApplyResult) GetComponent() ConfigComponent { + if x != nil { + return x.Component + } + return ConfigComponent_CONFIG_COMPONENT_UNSPECIFIED +} + +func (x *ConfigComponentApplyResult) GetRequestedRevision() *ConfigSnapshotRevision { + if x != nil { + return x.RequestedRevision + } + return nil +} + +func (x *ConfigComponentApplyResult) GetAppliedRevision() *ConfigSnapshotRevision { + if x != nil { + return x.AppliedRevision + } + return nil +} + +func (x *ConfigComponentApplyResult) GetOutcome() ConfigApplyOutcome { + if x != nil { + return x.Outcome + } + return ConfigApplyOutcome_CONFIG_APPLY_OUTCOME_UNSPECIFIED +} + +func (x *ConfigComponentApplyResult) GetFailure() *ConfigApplyFailure { + if x != nil { + return x.Failure + } + return nil +} + +// Application result for one ConfigUpdate. +type ConfigUpdateResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Echoes ConfigUpdate.update_id for session-local correlation. + UpdateId string `protobuf:"bytes,1,opt,name=update_id,json=updateId,proto3" json:"update_id,omitempty"` + // Echoes ConfigUpdate.component_sequence. + ComponentSequence uint64 `protobuf:"varint,2,opt,name=component_sequence,json=componentSequence,proto3" json:"component_sequence,omitempty"` + Result *ConfigComponentApplyResult `protobuf:"bytes,3,opt,name=result,proto3" json:"result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigUpdateResult) Reset() { + *x = ConfigUpdateResult{} + mi := &file_openshell_proto_msgTypes[174] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigUpdateResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigUpdateResult) ProtoMessage() {} + +func (x *ConfigUpdateResult) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[174] + 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 ConfigUpdateResult.ProtoReflect.Descriptor instead. +func (*ConfigUpdateResult) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{174} +} + +func (x *ConfigUpdateResult) GetUpdateId() string { + if x != nil { + return x.UpdateId + } + return "" +} + +func (x *ConfigUpdateResult) GetComponentSequence() uint64 { + if x != nil { + return x.ComponentSequence + } + return 0 +} + +func (x *ConfigUpdateResult) GetResult() *ConfigComponentApplyResult { + if x != nil { + return x.Result + } + return nil +} + +// Aggregate application result for the SessionAccepted bootstrap. +type ConfigBootstrapResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + Results []*ConfigComponentApplyResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfigBootstrapResult) Reset() { + *x = ConfigBootstrapResult{} + mi := &file_openshell_proto_msgTypes[175] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfigBootstrapResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigBootstrapResult) ProtoMessage() {} + +func (x *ConfigBootstrapResult) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[175] + 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 ConfigBootstrapResult.ProtoReflect.Descriptor instead. +func (*ConfigBootstrapResult) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{175} +} + +func (x *ConfigBootstrapResult) GetResults() []*ConfigComponentApplyResult { + if x != nil { + return x.Results + } + return nil +} + +// Gateway rejects the supervisor session. +type SessionRejected struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Human-readable rejection reason. + Reason string `protobuf:"bytes,1,opt,name=reason,proto3" json:"reason,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SessionRejected) Reset() { + *x = SessionRejected{} + mi := &file_openshell_proto_msgTypes[176] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionRejected) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionRejected) ProtoMessage() {} + +func (x *SessionRejected) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[176] + 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 SessionRejected.ProtoReflect.Descriptor instead. +func (*SessionRejected) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{176} +} + +func (x *SessionRejected) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +// Supervisor heartbeat. +type SupervisorHeartbeat struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SupervisorHeartbeat) Reset() { + *x = SupervisorHeartbeat{} + mi := &file_openshell_proto_msgTypes[177] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SupervisorHeartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SupervisorHeartbeat) ProtoMessage() {} + +func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[177] + 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 SupervisorHeartbeat.ProtoReflect.Descriptor instead. +func (*SupervisorHeartbeat) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{177} +} + +// Gateway heartbeat. +type GatewayHeartbeat struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GatewayHeartbeat) Reset() { + *x = GatewayHeartbeat{} + mi := &file_openshell_proto_msgTypes[178] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GatewayHeartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GatewayHeartbeat) ProtoMessage() {} + +func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[178] + 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 GatewayHeartbeat.ProtoReflect.Descriptor instead. +func (*GatewayHeartbeat) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{178} } // Terminal result reported before the supervisor shuts down. A successful RPC @@ -13639,7 +14343,7 @@ type ReportMainProcessExitRequest struct { func (x *ReportMainProcessExitRequest) Reset() { *x = ReportMainProcessExitRequest{} - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[179] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13651,7 +14355,7 @@ func (x *ReportMainProcessExitRequest) String() string { func (*ReportMainProcessExitRequest) ProtoMessage() {} func (x *ReportMainProcessExitRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[179] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13664,7 +14368,7 @@ func (x *ReportMainProcessExitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportMainProcessExitRequest.ProtoReflect.Descriptor instead. func (*ReportMainProcessExitRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{171} + return file_openshell_proto_rawDescGZIP(), []int{179} } func (x *ReportMainProcessExitRequest) GetSandboxId() string { @@ -13696,7 +14400,7 @@ type ReportMainProcessExitResponse struct { func (x *ReportMainProcessExitResponse) Reset() { *x = ReportMainProcessExitResponse{} - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[180] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13708,7 +14412,7 @@ func (x *ReportMainProcessExitResponse) String() string { func (*ReportMainProcessExitResponse) ProtoMessage() {} func (x *ReportMainProcessExitResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[180] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13721,7 +14425,7 @@ func (x *ReportMainProcessExitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportMainProcessExitResponse.ProtoReflect.Descriptor instead. func (*ReportMainProcessExitResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{172} + return file_openshell_proto_rawDescGZIP(), []int{180} } // Terminal-delivery completion reported after all expected foreground SSH @@ -13736,7 +14440,7 @@ type FinalizeMainProcessExitRequest struct { func (x *FinalizeMainProcessExitRequest) Reset() { *x = FinalizeMainProcessExitRequest{} - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[181] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13748,7 +14452,7 @@ func (x *FinalizeMainProcessExitRequest) String() string { func (*FinalizeMainProcessExitRequest) ProtoMessage() {} func (x *FinalizeMainProcessExitRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[181] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13761,7 +14465,7 @@ func (x *FinalizeMainProcessExitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizeMainProcessExitRequest.ProtoReflect.Descriptor instead. func (*FinalizeMainProcessExitRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{173} + return file_openshell_proto_rawDescGZIP(), []int{181} } func (x *FinalizeMainProcessExitRequest) GetSandboxId() string { @@ -13786,7 +14490,7 @@ type FinalizeMainProcessExitResponse struct { func (x *FinalizeMainProcessExitResponse) Reset() { *x = FinalizeMainProcessExitResponse{} - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[182] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13798,7 +14502,7 @@ func (x *FinalizeMainProcessExitResponse) String() string { func (*FinalizeMainProcessExitResponse) ProtoMessage() {} func (x *FinalizeMainProcessExitResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[182] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13811,7 +14515,7 @@ func (x *FinalizeMainProcessExitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizeMainProcessExitResponse.ProtoReflect.Descriptor instead. func (*FinalizeMainProcessExitResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{174} + return file_openshell_proto_rawDescGZIP(), []int{182} } // Gateway requests the supervisor to open a relay channel. @@ -13840,7 +14544,7 @@ type RelayOpen struct { func (x *RelayOpen) Reset() { *x = RelayOpen{} - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[183] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13852,7 +14556,7 @@ func (x *RelayOpen) String() string { func (*RelayOpen) ProtoMessage() {} func (x *RelayOpen) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[183] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13865,7 +14569,7 @@ func (x *RelayOpen) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpen.ProtoReflect.Descriptor instead. func (*RelayOpen) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{175} + return file_openshell_proto_rawDescGZIP(), []int{183} } func (x *RelayOpen) GetChannelId() string { @@ -13932,7 +14636,7 @@ type SshRelayTarget struct { func (x *SshRelayTarget) Reset() { *x = SshRelayTarget{} - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[184] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13944,7 +14648,7 @@ func (x *SshRelayTarget) String() string { func (*SshRelayTarget) ProtoMessage() {} func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[184] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13957,7 +14661,7 @@ func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use SshRelayTarget.ProtoReflect.Descriptor instead. func (*SshRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{176} + return file_openshell_proto_rawDescGZIP(), []int{184} } // TCP target dialed by the supervisor from inside the sandbox. @@ -13973,7 +14677,7 @@ type TcpRelayTarget struct { func (x *TcpRelayTarget) Reset() { *x = TcpRelayTarget{} - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[185] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13985,7 +14689,7 @@ func (x *TcpRelayTarget) String() string { func (*TcpRelayTarget) ProtoMessage() {} func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[185] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13998,7 +14702,7 @@ func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpRelayTarget.ProtoReflect.Descriptor instead. func (*TcpRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{177} + return file_openshell_proto_rawDescGZIP(), []int{185} } func (x *TcpRelayTarget) GetHost() string { @@ -14026,7 +14730,7 @@ type RelayInit struct { func (x *RelayInit) Reset() { *x = RelayInit{} - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[186] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14038,7 +14742,7 @@ func (x *RelayInit) String() string { func (*RelayInit) ProtoMessage() {} func (x *RelayInit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[186] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14051,7 +14755,7 @@ func (x *RelayInit) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayInit.ProtoReflect.Descriptor instead. func (*RelayInit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{178} + return file_openshell_proto_rawDescGZIP(), []int{186} } func (x *RelayInit) GetChannelId() string { @@ -14078,7 +14782,7 @@ type RelayFrame struct { func (x *RelayFrame) Reset() { *x = RelayFrame{} - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[187] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14090,7 +14794,7 @@ func (x *RelayFrame) String() string { func (*RelayFrame) ProtoMessage() {} func (x *RelayFrame) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[187] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14103,7 +14807,7 @@ func (x *RelayFrame) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayFrame.ProtoReflect.Descriptor instead. func (*RelayFrame) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{179} + return file_openshell_proto_rawDescGZIP(), []int{187} } func (x *RelayFrame) GetPayload() isRelayFrame_Payload { @@ -14163,7 +14867,7 @@ type PeerRelayInit struct { func (x *PeerRelayInit) Reset() { *x = PeerRelayInit{} - mi := &file_openshell_proto_msgTypes[180] + mi := &file_openshell_proto_msgTypes[188] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14175,7 +14879,7 @@ func (x *PeerRelayInit) String() string { func (*PeerRelayInit) ProtoMessage() {} func (x *PeerRelayInit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[180] + mi := &file_openshell_proto_msgTypes[188] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14188,7 +14892,7 @@ func (x *PeerRelayInit) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerRelayInit.ProtoReflect.Descriptor instead. func (*PeerRelayInit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{180} + return file_openshell_proto_rawDescGZIP(), []int{188} } func (x *PeerRelayInit) GetSandboxId() string { @@ -14226,7 +14930,7 @@ type PeerRelayFrame struct { func (x *PeerRelayFrame) Reset() { *x = PeerRelayFrame{} - mi := &file_openshell_proto_msgTypes[181] + mi := &file_openshell_proto_msgTypes[189] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14238,7 +14942,7 @@ func (x *PeerRelayFrame) String() string { func (*PeerRelayFrame) ProtoMessage() {} func (x *PeerRelayFrame) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[181] + mi := &file_openshell_proto_msgTypes[189] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14251,7 +14955,7 @@ func (x *PeerRelayFrame) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerRelayFrame.ProtoReflect.Descriptor instead. func (*PeerRelayFrame) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{181} + return file_openshell_proto_rawDescGZIP(), []int{189} } func (x *PeerRelayFrame) GetPayload() isPeerRelayFrame_Payload { @@ -14295,6 +14999,227 @@ func (*PeerRelayFrame_Init) isPeerRelayFrame_Payload() {} func (*PeerRelayFrame_Data) isPeerRelayFrame_Payload() {} +type PeerConfigSandboxTarget struct { + state protoimpl.MessageState `protogen:"open.v1"` + SandboxId string `protobuf:"bytes,1,opt,name=sandbox_id,json=sandboxId,proto3" json:"sandbox_id,omitempty"` + // Fences a targeted hint to the session observed by the sending replica. + SessionId string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerConfigSandboxTarget) Reset() { + *x = PeerConfigSandboxTarget{} + mi := &file_openshell_proto_msgTypes[190] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerConfigSandboxTarget) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerConfigSandboxTarget) ProtoMessage() {} + +func (x *PeerConfigSandboxTarget) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[190] + 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 PeerConfigSandboxTarget.ProtoReflect.Descriptor instead. +func (*PeerConfigSandboxTarget) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{190} +} + +func (x *PeerConfigSandboxTarget) GetSandboxId() string { + if x != nil { + return x.SandboxId + } + return "" +} + +func (x *PeerConfigSandboxTarget) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +type PeerConfigUpdateHintRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Scope: + // + // *PeerConfigUpdateHintRequest_Sandbox + // *PeerConfigUpdateHintRequest_Workspace + // *PeerConfigUpdateHintRequest_AllConnected + Scope isPeerConfigUpdateHintRequest_Scope `protobuf_oneof:"scope"` + SandboxConfig bool `protobuf:"varint,4,opt,name=sandbox_config,json=sandboxConfig,proto3" json:"sandbox_config,omitempty"` + ProviderEnvironment bool `protobuf:"varint,5,opt,name=provider_environment,json=providerEnvironment,proto3" json:"provider_environment,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerConfigUpdateHintRequest) Reset() { + *x = PeerConfigUpdateHintRequest{} + mi := &file_openshell_proto_msgTypes[191] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerConfigUpdateHintRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerConfigUpdateHintRequest) ProtoMessage() {} + +func (x *PeerConfigUpdateHintRequest) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[191] + 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 PeerConfigUpdateHintRequest.ProtoReflect.Descriptor instead. +func (*PeerConfigUpdateHintRequest) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{191} +} + +func (x *PeerConfigUpdateHintRequest) GetScope() isPeerConfigUpdateHintRequest_Scope { + if x != nil { + return x.Scope + } + return nil +} + +func (x *PeerConfigUpdateHintRequest) GetSandbox() *PeerConfigSandboxTarget { + if x != nil { + if x, ok := x.Scope.(*PeerConfigUpdateHintRequest_Sandbox); ok { + return x.Sandbox + } + } + return nil +} + +func (x *PeerConfigUpdateHintRequest) GetWorkspace() string { + if x != nil { + if x, ok := x.Scope.(*PeerConfigUpdateHintRequest_Workspace); ok { + return x.Workspace + } + } + return "" +} + +func (x *PeerConfigUpdateHintRequest) GetAllConnected() bool { + if x != nil { + if x, ok := x.Scope.(*PeerConfigUpdateHintRequest_AllConnected); ok { + return x.AllConnected + } + } + return false +} + +func (x *PeerConfigUpdateHintRequest) GetSandboxConfig() bool { + if x != nil { + return x.SandboxConfig + } + return false +} + +func (x *PeerConfigUpdateHintRequest) GetProviderEnvironment() bool { + if x != nil { + return x.ProviderEnvironment + } + return false +} + +type isPeerConfigUpdateHintRequest_Scope interface { + isPeerConfigUpdateHintRequest_Scope() +} + +type PeerConfigUpdateHintRequest_Sandbox struct { + Sandbox *PeerConfigSandboxTarget `protobuf:"bytes,1,opt,name=sandbox,proto3,oneof"` +} + +type PeerConfigUpdateHintRequest_Workspace struct { + Workspace string `protobuf:"bytes,2,opt,name=workspace,proto3,oneof"` +} + +type PeerConfigUpdateHintRequest_AllConnected struct { + AllConnected bool `protobuf:"varint,3,opt,name=all_connected,json=allConnected,proto3,oneof"` +} + +func (*PeerConfigUpdateHintRequest_Sandbox) isPeerConfigUpdateHintRequest_Scope() {} + +func (*PeerConfigUpdateHintRequest_Workspace) isPeerConfigUpdateHintRequest_Scope() {} + +func (*PeerConfigUpdateHintRequest_AllConnected) isPeerConfigUpdateHintRequest_Scope() {} + +type PeerConfigUpdateHintResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The targeted session moved before the receiving replica accepted the hint. + StaleOwner bool `protobuf:"varint,1,opt,name=stale_owner,json=staleOwner,proto3" json:"stale_owner,omitempty"` + // The bounded local delivery or fanout queue could not accept the hint. + QueueFull bool `protobuf:"varint,2,opt,name=queue_full,json=queueFull,proto3" json:"queue_full,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PeerConfigUpdateHintResponse) Reset() { + *x = PeerConfigUpdateHintResponse{} + mi := &file_openshell_proto_msgTypes[192] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PeerConfigUpdateHintResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerConfigUpdateHintResponse) ProtoMessage() {} + +func (x *PeerConfigUpdateHintResponse) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[192] + 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 PeerConfigUpdateHintResponse.ProtoReflect.Descriptor instead. +func (*PeerConfigUpdateHintResponse) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{192} +} + +func (x *PeerConfigUpdateHintResponse) GetStaleOwner() bool { + if x != nil { + return x.StaleOwner + } + return false +} + +func (x *PeerConfigUpdateHintResponse) GetQueueFull() bool { + if x != nil { + return x.QueueFull + } + return false +} + // Supervisor reports the result of a relay open request. type RelayOpenResult struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -14310,7 +15235,7 @@ type RelayOpenResult struct { func (x *RelayOpenResult) Reset() { *x = RelayOpenResult{} - mi := &file_openshell_proto_msgTypes[182] + mi := &file_openshell_proto_msgTypes[193] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14322,7 +15247,7 @@ func (x *RelayOpenResult) String() string { func (*RelayOpenResult) ProtoMessage() {} func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[182] + mi := &file_openshell_proto_msgTypes[193] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14335,7 +15260,7 @@ func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpenResult.ProtoReflect.Descriptor instead. func (*RelayOpenResult) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{182} + return file_openshell_proto_rawDescGZIP(), []int{193} } func (x *RelayOpenResult) GetChannelId() string { @@ -14372,7 +15297,7 @@ type RelayClose struct { func (x *RelayClose) Reset() { *x = RelayClose{} - mi := &file_openshell_proto_msgTypes[183] + mi := &file_openshell_proto_msgTypes[194] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14384,7 +15309,7 @@ func (x *RelayClose) String() string { func (*RelayClose) ProtoMessage() {} func (x *RelayClose) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[183] + mi := &file_openshell_proto_msgTypes[194] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14397,7 +15322,7 @@ func (x *RelayClose) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayClose.ProtoReflect.Descriptor instead. func (*RelayClose) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{183} + return file_openshell_proto_rawDescGZIP(), []int{194} } func (x *RelayClose) GetChannelId() string { @@ -14431,7 +15356,7 @@ type L7RequestSample struct { func (x *L7RequestSample) Reset() { *x = L7RequestSample{} - mi := &file_openshell_proto_msgTypes[184] + mi := &file_openshell_proto_msgTypes[195] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14443,7 +15368,7 @@ func (x *L7RequestSample) String() string { func (*L7RequestSample) ProtoMessage() {} func (x *L7RequestSample) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[184] + mi := &file_openshell_proto_msgTypes[195] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14456,7 +15381,7 @@ func (x *L7RequestSample) ProtoReflect() protoreflect.Message { // Deprecated: Use L7RequestSample.ProtoReflect.Descriptor instead. func (*L7RequestSample) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{184} + return file_openshell_proto_rawDescGZIP(), []int{195} } func (x *L7RequestSample) GetMethod() string { @@ -14530,7 +15455,7 @@ type DenialSummary struct { func (x *DenialSummary) Reset() { *x = DenialSummary{} - mi := &file_openshell_proto_msgTypes[185] + mi := &file_openshell_proto_msgTypes[196] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14542,7 +15467,7 @@ func (x *DenialSummary) String() string { func (*DenialSummary) ProtoMessage() {} func (x *DenialSummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[185] + mi := &file_openshell_proto_msgTypes[196] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14555,7 +15480,7 @@ func (x *DenialSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialSummary.ProtoReflect.Descriptor instead. func (*DenialSummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{185} + return file_openshell_proto_rawDescGZIP(), []int{196} } func (x *DenialSummary) GetSandboxId() string { @@ -14690,7 +15615,7 @@ type DenialGroupCount struct { func (x *DenialGroupCount) Reset() { *x = DenialGroupCount{} - mi := &file_openshell_proto_msgTypes[186] + mi := &file_openshell_proto_msgTypes[197] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14702,7 +15627,7 @@ func (x *DenialGroupCount) String() string { func (*DenialGroupCount) ProtoMessage() {} func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[186] + mi := &file_openshell_proto_msgTypes[197] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14715,7 +15640,7 @@ func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialGroupCount.ProtoReflect.Descriptor instead. func (*DenialGroupCount) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{186} + return file_openshell_proto_rawDescGZIP(), []int{197} } func (x *DenialGroupCount) GetDenyGroup() string { @@ -14748,7 +15673,7 @@ type NetworkActivitySummary struct { func (x *NetworkActivitySummary) Reset() { *x = NetworkActivitySummary{} - mi := &file_openshell_proto_msgTypes[187] + mi := &file_openshell_proto_msgTypes[198] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14760,7 +15685,7 @@ func (x *NetworkActivitySummary) String() string { func (*NetworkActivitySummary) ProtoMessage() {} func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[187] + mi := &file_openshell_proto_msgTypes[198] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14773,7 +15698,7 @@ func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkActivitySummary.ProtoReflect.Descriptor instead. func (*NetworkActivitySummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{187} + return file_openshell_proto_rawDescGZIP(), []int{198} } func (x *NetworkActivitySummary) GetNetworkActivityCount() uint32 { @@ -14861,7 +15786,7 @@ type PolicyChunk struct { func (x *PolicyChunk) Reset() { *x = PolicyChunk{} - mi := &file_openshell_proto_msgTypes[188] + mi := &file_openshell_proto_msgTypes[199] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14873,7 +15798,7 @@ func (x *PolicyChunk) String() string { func (*PolicyChunk) ProtoMessage() {} func (x *PolicyChunk) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[188] + mi := &file_openshell_proto_msgTypes[199] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14886,7 +15811,7 @@ func (x *PolicyChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyChunk.ProtoReflect.Descriptor instead. func (*PolicyChunk) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{188} + return file_openshell_proto_rawDescGZIP(), []int{199} } func (x *PolicyChunk) GetId() string { @@ -15074,7 +15999,7 @@ type DraftPolicyUpdate struct { func (x *DraftPolicyUpdate) Reset() { *x = DraftPolicyUpdate{} - mi := &file_openshell_proto_msgTypes[189] + mi := &file_openshell_proto_msgTypes[200] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15086,7 +16011,7 @@ func (x *DraftPolicyUpdate) String() string { func (*DraftPolicyUpdate) ProtoMessage() {} func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[189] + mi := &file_openshell_proto_msgTypes[200] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15099,7 +16024,7 @@ func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftPolicyUpdate.ProtoReflect.Descriptor instead. func (*DraftPolicyUpdate) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{189} + return file_openshell_proto_rawDescGZIP(), []int{200} } func (x *DraftPolicyUpdate) GetDraftVersion() uint64 { @@ -15158,7 +16083,7 @@ type SubmitPolicyAnalysisRequest struct { func (x *SubmitPolicyAnalysisRequest) Reset() { *x = SubmitPolicyAnalysisRequest{} - mi := &file_openshell_proto_msgTypes[190] + mi := &file_openshell_proto_msgTypes[201] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15170,7 +16095,7 @@ func (x *SubmitPolicyAnalysisRequest) String() string { func (*SubmitPolicyAnalysisRequest) ProtoMessage() {} func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[190] + mi := &file_openshell_proto_msgTypes[201] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15183,7 +16108,7 @@ func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisRequest.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{190} + return file_openshell_proto_rawDescGZIP(), []int{201} } func (x *SubmitPolicyAnalysisRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -15246,7 +16171,7 @@ type SubmitPolicyAnalysisResponse struct { func (x *SubmitPolicyAnalysisResponse) Reset() { *x = SubmitPolicyAnalysisResponse{} - mi := &file_openshell_proto_msgTypes[191] + mi := &file_openshell_proto_msgTypes[202] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15258,7 +16183,7 @@ func (x *SubmitPolicyAnalysisResponse) String() string { func (*SubmitPolicyAnalysisResponse) ProtoMessage() {} func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[191] + mi := &file_openshell_proto_msgTypes[202] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15271,7 +16196,7 @@ func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisResponse.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{191} + return file_openshell_proto_rawDescGZIP(), []int{202} } func (x *SubmitPolicyAnalysisResponse) GetAcceptedChunks() uint32 { @@ -15316,7 +16241,7 @@ type GetDraftPolicyRequest struct { func (x *GetDraftPolicyRequest) Reset() { *x = GetDraftPolicyRequest{} - mi := &file_openshell_proto_msgTypes[192] + mi := &file_openshell_proto_msgTypes[203] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15328,7 +16253,7 @@ func (x *GetDraftPolicyRequest) String() string { func (*GetDraftPolicyRequest) ProtoMessage() {} func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[192] + mi := &file_openshell_proto_msgTypes[203] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15341,7 +16266,7 @@ func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyRequest.ProtoReflect.Descriptor instead. func (*GetDraftPolicyRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{192} + return file_openshell_proto_rawDescGZIP(), []int{203} } func (x *GetDraftPolicyRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -15381,7 +16306,7 @@ type GetDraftPolicyResponse struct { func (x *GetDraftPolicyResponse) Reset() { *x = GetDraftPolicyResponse{} - mi := &file_openshell_proto_msgTypes[193] + mi := &file_openshell_proto_msgTypes[204] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15393,7 +16318,7 @@ func (x *GetDraftPolicyResponse) String() string { func (*GetDraftPolicyResponse) ProtoMessage() {} func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[193] + mi := &file_openshell_proto_msgTypes[204] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15406,7 +16331,7 @@ func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyResponse.ProtoReflect.Descriptor instead. func (*GetDraftPolicyResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{193} + return file_openshell_proto_rawDescGZIP(), []int{204} } func (x *GetDraftPolicyResponse) GetChunks() []*PolicyChunk { @@ -15457,7 +16382,7 @@ type ApproveDraftChunkRequest struct { func (x *ApproveDraftChunkRequest) Reset() { *x = ApproveDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[194] + mi := &file_openshell_proto_msgTypes[205] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15469,7 +16394,7 @@ func (x *ApproveDraftChunkRequest) String() string { func (*ApproveDraftChunkRequest) ProtoMessage() {} func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[194] + mi := &file_openshell_proto_msgTypes[205] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15482,7 +16407,7 @@ func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkRequest.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{194} + return file_openshell_proto_rawDescGZIP(), []int{205} } func (x *ApproveDraftChunkRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -15532,7 +16457,7 @@ type ApproveDraftChunkResponse struct { func (x *ApproveDraftChunkResponse) Reset() { *x = ApproveDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[195] + mi := &file_openshell_proto_msgTypes[206] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15544,7 +16469,7 @@ func (x *ApproveDraftChunkResponse) String() string { func (*ApproveDraftChunkResponse) ProtoMessage() {} func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[195] + mi := &file_openshell_proto_msgTypes[206] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15557,7 +16482,7 @@ func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkResponse.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{195} + return file_openshell_proto_rawDescGZIP(), []int{206} } func (x *ApproveDraftChunkResponse) GetPolicyVersion() uint32 { @@ -15593,7 +16518,7 @@ type RejectDraftChunkRequest struct { func (x *RejectDraftChunkRequest) Reset() { *x = RejectDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[196] + mi := &file_openshell_proto_msgTypes[207] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15605,7 +16530,7 @@ func (x *RejectDraftChunkRequest) String() string { func (*RejectDraftChunkRequest) ProtoMessage() {} func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[196] + mi := &file_openshell_proto_msgTypes[207] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15618,7 +16543,7 @@ func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkRequest.ProtoReflect.Descriptor instead. func (*RejectDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{196} + return file_openshell_proto_rawDescGZIP(), []int{207} } func (x *RejectDraftChunkRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -15664,7 +16589,7 @@ type RejectDraftChunkResponse struct { func (x *RejectDraftChunkResponse) Reset() { *x = RejectDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[197] + mi := &file_openshell_proto_msgTypes[208] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15676,7 +16601,7 @@ func (x *RejectDraftChunkResponse) String() string { func (*RejectDraftChunkResponse) ProtoMessage() {} func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[197] + mi := &file_openshell_proto_msgTypes[208] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15689,7 +16614,7 @@ func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkResponse.ProtoReflect.Descriptor instead. func (*RejectDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{197} + return file_openshell_proto_rawDescGZIP(), []int{208} } // Approve all pending chunks. @@ -15703,7 +16628,7 @@ type DraftChunkApproval struct { func (x *DraftChunkApproval) Reset() { *x = DraftChunkApproval{} - mi := &file_openshell_proto_msgTypes[198] + mi := &file_openshell_proto_msgTypes[209] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15715,7 +16640,7 @@ func (x *DraftChunkApproval) String() string { func (*DraftChunkApproval) ProtoMessage() {} func (x *DraftChunkApproval) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[198] + mi := &file_openshell_proto_msgTypes[209] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15728,7 +16653,7 @@ func (x *DraftChunkApproval) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftChunkApproval.ProtoReflect.Descriptor instead. func (*DraftChunkApproval) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{198} + return file_openshell_proto_rawDescGZIP(), []int{209} } func (x *DraftChunkApproval) GetChunkId() string { @@ -15764,7 +16689,7 @@ type ApproveAllDraftChunksRequest struct { func (x *ApproveAllDraftChunksRequest) Reset() { *x = ApproveAllDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[199] + mi := &file_openshell_proto_msgTypes[210] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15776,7 +16701,7 @@ func (x *ApproveAllDraftChunksRequest) String() string { func (*ApproveAllDraftChunksRequest) ProtoMessage() {} func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[199] + mi := &file_openshell_proto_msgTypes[210] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15789,7 +16714,7 @@ func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{199} + return file_openshell_proto_rawDescGZIP(), []int{210} } func (x *ApproveAllDraftChunksRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -15844,7 +16769,7 @@ type ApproveAllDraftChunksResponse struct { func (x *ApproveAllDraftChunksResponse) Reset() { *x = ApproveAllDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[200] + mi := &file_openshell_proto_msgTypes[211] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15856,7 +16781,7 @@ func (x *ApproveAllDraftChunksResponse) String() string { func (*ApproveAllDraftChunksResponse) ProtoMessage() {} func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[200] + mi := &file_openshell_proto_msgTypes[211] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15869,7 +16794,7 @@ func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{200} + return file_openshell_proto_rawDescGZIP(), []int{211} } func (x *ApproveAllDraftChunksResponse) GetPolicyVersion() uint32 { @@ -15919,7 +16844,7 @@ type EditDraftChunkRequest struct { func (x *EditDraftChunkRequest) Reset() { *x = EditDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[201] + mi := &file_openshell_proto_msgTypes[212] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15931,7 +16856,7 @@ func (x *EditDraftChunkRequest) String() string { func (*EditDraftChunkRequest) ProtoMessage() {} func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[201] + mi := &file_openshell_proto_msgTypes[212] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15944,7 +16869,7 @@ func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkRequest.ProtoReflect.Descriptor instead. func (*EditDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{201} + return file_openshell_proto_rawDescGZIP(), []int{212} } func (x *EditDraftChunkRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -15990,7 +16915,7 @@ type EditDraftChunkResponse struct { func (x *EditDraftChunkResponse) Reset() { *x = EditDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[202] + mi := &file_openshell_proto_msgTypes[213] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16002,7 +16927,7 @@ func (x *EditDraftChunkResponse) String() string { func (*EditDraftChunkResponse) ProtoMessage() {} func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[202] + mi := &file_openshell_proto_msgTypes[213] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16015,7 +16940,7 @@ func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkResponse.ProtoReflect.Descriptor instead. func (*EditDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{202} + return file_openshell_proto_rawDescGZIP(), []int{213} } // Reverse an approval (remove merged rule from active policy). @@ -16035,7 +16960,7 @@ type UndoDraftChunkRequest struct { func (x *UndoDraftChunkRequest) Reset() { *x = UndoDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[203] + mi := &file_openshell_proto_msgTypes[214] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16047,7 +16972,7 @@ func (x *UndoDraftChunkRequest) String() string { func (*UndoDraftChunkRequest) ProtoMessage() {} func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[203] + mi := &file_openshell_proto_msgTypes[214] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16060,7 +16985,7 @@ func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkRequest.ProtoReflect.Descriptor instead. func (*UndoDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{203} + return file_openshell_proto_rawDescGZIP(), []int{214} } func (x *UndoDraftChunkRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -16103,7 +17028,7 @@ type UndoDraftChunkResponse struct { func (x *UndoDraftChunkResponse) Reset() { *x = UndoDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[204] + mi := &file_openshell_proto_msgTypes[215] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16115,7 +17040,7 @@ func (x *UndoDraftChunkResponse) String() string { func (*UndoDraftChunkResponse) ProtoMessage() {} func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[204] + mi := &file_openshell_proto_msgTypes[215] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16128,7 +17053,7 @@ func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkResponse.ProtoReflect.Descriptor instead. func (*UndoDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{204} + return file_openshell_proto_rawDescGZIP(), []int{215} } func (x *UndoDraftChunkResponse) GetPolicyVersion() uint32 { @@ -16160,7 +17085,7 @@ type ClearDraftChunksRequest struct { func (x *ClearDraftChunksRequest) Reset() { *x = ClearDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[205] + mi := &file_openshell_proto_msgTypes[216] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16172,7 +17097,7 @@ func (x *ClearDraftChunksRequest) String() string { func (*ClearDraftChunksRequest) ProtoMessage() {} func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[205] + mi := &file_openshell_proto_msgTypes[216] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16185,7 +17110,7 @@ func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ClearDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{205} + return file_openshell_proto_rawDescGZIP(), []int{216} } func (x *ClearDraftChunksRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -16219,7 +17144,7 @@ type ClearDraftChunksResponse struct { func (x *ClearDraftChunksResponse) Reset() { *x = ClearDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[206] + mi := &file_openshell_proto_msgTypes[217] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16231,7 +17156,7 @@ func (x *ClearDraftChunksResponse) String() string { func (*ClearDraftChunksResponse) ProtoMessage() {} func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[206] + mi := &file_openshell_proto_msgTypes[217] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16244,7 +17169,7 @@ func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ClearDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{206} + return file_openshell_proto_rawDescGZIP(), []int{217} } func (x *ClearDraftChunksResponse) GetChunksCleared() uint32 { @@ -16266,7 +17191,7 @@ type GetDraftHistoryRequest struct { func (x *GetDraftHistoryRequest) Reset() { *x = GetDraftHistoryRequest{} - mi := &file_openshell_proto_msgTypes[207] + mi := &file_openshell_proto_msgTypes[218] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16278,7 +17203,7 @@ func (x *GetDraftHistoryRequest) String() string { func (*GetDraftHistoryRequest) ProtoMessage() {} func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[207] + mi := &file_openshell_proto_msgTypes[218] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16291,7 +17216,7 @@ func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryRequest.ProtoReflect.Descriptor instead. func (*GetDraftHistoryRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{207} + return file_openshell_proto_rawDescGZIP(), []int{218} } func (x *GetDraftHistoryRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -16325,7 +17250,7 @@ type DraftHistoryEntry struct { func (x *DraftHistoryEntry) Reset() { *x = DraftHistoryEntry{} - mi := &file_openshell_proto_msgTypes[208] + mi := &file_openshell_proto_msgTypes[219] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16337,7 +17262,7 @@ func (x *DraftHistoryEntry) String() string { func (*DraftHistoryEntry) ProtoMessage() {} func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[208] + mi := &file_openshell_proto_msgTypes[219] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16350,7 +17275,7 @@ func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftHistoryEntry.ProtoReflect.Descriptor instead. func (*DraftHistoryEntry) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{208} + return file_openshell_proto_rawDescGZIP(), []int{219} } func (x *DraftHistoryEntry) GetEventTime() *timestamppb.Timestamp { @@ -16391,7 +17316,7 @@ type GetDraftHistoryResponse struct { func (x *GetDraftHistoryResponse) Reset() { *x = GetDraftHistoryResponse{} - mi := &file_openshell_proto_msgTypes[209] + mi := &file_openshell_proto_msgTypes[220] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16403,7 +17328,7 @@ func (x *GetDraftHistoryResponse) String() string { func (*GetDraftHistoryResponse) ProtoMessage() {} func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[209] + mi := &file_openshell_proto_msgTypes[220] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16416,7 +17341,7 @@ func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryResponse.ProtoReflect.Descriptor instead. func (*GetDraftHistoryResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{209} + return file_openshell_proto_rawDescGZIP(), []int{220} } func (x *GetDraftHistoryResponse) GetEntries() []*DraftHistoryEntry { @@ -16441,7 +17366,7 @@ type CreateWorkspaceRequest struct { func (x *CreateWorkspaceRequest) Reset() { *x = CreateWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[210] + mi := &file_openshell_proto_msgTypes[221] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16453,7 +17378,7 @@ func (x *CreateWorkspaceRequest) String() string { func (*CreateWorkspaceRequest) ProtoMessage() {} func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[210] + mi := &file_openshell_proto_msgTypes[221] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16466,7 +17391,7 @@ func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceRequest.ProtoReflect.Descriptor instead. func (*CreateWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{210} + return file_openshell_proto_rawDescGZIP(), []int{221} } func (x *CreateWorkspaceRequest) GetName() string { @@ -16500,7 +17425,7 @@ type CreateWorkspaceResponse struct { func (x *CreateWorkspaceResponse) Reset() { *x = CreateWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[211] + mi := &file_openshell_proto_msgTypes[222] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16512,7 +17437,7 @@ func (x *CreateWorkspaceResponse) String() string { func (*CreateWorkspaceResponse) ProtoMessage() {} func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[211] + mi := &file_openshell_proto_msgTypes[222] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16525,7 +17450,7 @@ func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceResponse.ProtoReflect.Descriptor instead. func (*CreateWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{211} + return file_openshell_proto_rawDescGZIP(), []int{222} } func (x *CreateWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -16546,7 +17471,7 @@ type GetWorkspaceRequest struct { func (x *GetWorkspaceRequest) Reset() { *x = GetWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[212] + mi := &file_openshell_proto_msgTypes[223] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16558,7 +17483,7 @@ func (x *GetWorkspaceRequest) String() string { func (*GetWorkspaceRequest) ProtoMessage() {} func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[212] + mi := &file_openshell_proto_msgTypes[223] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16571,7 +17496,7 @@ func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceRequest.ProtoReflect.Descriptor instead. func (*GetWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{212} + return file_openshell_proto_rawDescGZIP(), []int{223} } func (x *GetWorkspaceRequest) GetName() string { @@ -16591,7 +17516,7 @@ type GetWorkspaceResponse struct { func (x *GetWorkspaceResponse) Reset() { *x = GetWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[213] + mi := &file_openshell_proto_msgTypes[224] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16603,7 +17528,7 @@ func (x *GetWorkspaceResponse) String() string { func (*GetWorkspaceResponse) ProtoMessage() {} func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[213] + mi := &file_openshell_proto_msgTypes[224] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16616,7 +17541,7 @@ func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceResponse.ProtoReflect.Descriptor instead. func (*GetWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{213} + return file_openshell_proto_rawDescGZIP(), []int{224} } func (x *GetWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -16643,7 +17568,7 @@ type ListWorkspacesRequest struct { func (x *ListWorkspacesRequest) Reset() { *x = ListWorkspacesRequest{} - mi := &file_openshell_proto_msgTypes[214] + mi := &file_openshell_proto_msgTypes[225] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16655,7 +17580,7 @@ func (x *ListWorkspacesRequest) String() string { func (*ListWorkspacesRequest) ProtoMessage() {} func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[214] + mi := &file_openshell_proto_msgTypes[225] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16668,7 +17593,7 @@ func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesRequest.ProtoReflect.Descriptor instead. func (*ListWorkspacesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{214} + return file_openshell_proto_rawDescGZIP(), []int{225} } func (x *ListWorkspacesRequest) GetPageSize() int32 { @@ -16704,7 +17629,7 @@ type ListWorkspacesResponse struct { func (x *ListWorkspacesResponse) Reset() { *x = ListWorkspacesResponse{} - mi := &file_openshell_proto_msgTypes[215] + mi := &file_openshell_proto_msgTypes[226] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16716,7 +17641,7 @@ func (x *ListWorkspacesResponse) String() string { func (*ListWorkspacesResponse) ProtoMessage() {} func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[215] + mi := &file_openshell_proto_msgTypes[226] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16729,7 +17654,7 @@ func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesResponse.ProtoReflect.Descriptor instead. func (*ListWorkspacesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{215} + return file_openshell_proto_rawDescGZIP(), []int{226} } func (x *ListWorkspacesResponse) GetWorkspaces() []*datamodelv1.Workspace { @@ -16760,7 +17685,7 @@ type DeleteWorkspaceRequest struct { func (x *DeleteWorkspaceRequest) Reset() { *x = DeleteWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[216] + mi := &file_openshell_proto_msgTypes[227] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16772,7 +17697,7 @@ func (x *DeleteWorkspaceRequest) String() string { func (*DeleteWorkspaceRequest) ProtoMessage() {} func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[216] + mi := &file_openshell_proto_msgTypes[227] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16785,7 +17710,7 @@ func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{216} + return file_openshell_proto_rawDescGZIP(), []int{227} } func (x *DeleteWorkspaceRequest) GetName() string { @@ -16819,7 +17744,7 @@ type DeleteWorkspaceResponse struct { func (x *DeleteWorkspaceResponse) Reset() { *x = DeleteWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[217] + mi := &file_openshell_proto_msgTypes[228] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16831,7 +17756,7 @@ func (x *DeleteWorkspaceResponse) String() string { func (*DeleteWorkspaceResponse) ProtoMessage() {} func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[217] + mi := &file_openshell_proto_msgTypes[228] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16844,7 +17769,7 @@ func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceResponse.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{217} + return file_openshell_proto_rawDescGZIP(), []int{228} } func (x *DeleteWorkspaceResponse) GetOutcome() DeletionOutcome { @@ -16868,7 +17793,7 @@ type WorkspaceMember struct { func (x *WorkspaceMember) Reset() { *x = WorkspaceMember{} - mi := &file_openshell_proto_msgTypes[218] + mi := &file_openshell_proto_msgTypes[229] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16880,7 +17805,7 @@ func (x *WorkspaceMember) String() string { func (*WorkspaceMember) ProtoMessage() {} func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[218] + mi := &file_openshell_proto_msgTypes[229] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16893,7 +17818,7 @@ func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkspaceMember.ProtoReflect.Descriptor instead. func (*WorkspaceMember) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{218} + return file_openshell_proto_rawDescGZIP(), []int{229} } func (x *WorkspaceMember) GetMetadata() *datamodelv1.ObjectMeta { @@ -16934,7 +17859,7 @@ type AddWorkspaceMemberRequest struct { func (x *AddWorkspaceMemberRequest) Reset() { *x = AddWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[219] + mi := &file_openshell_proto_msgTypes[230] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16946,7 +17871,7 @@ func (x *AddWorkspaceMemberRequest) String() string { func (*AddWorkspaceMemberRequest) ProtoMessage() {} func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[219] + mi := &file_openshell_proto_msgTypes[230] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16959,7 +17884,7 @@ func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{219} + return file_openshell_proto_rawDescGZIP(), []int{230} } func (x *AddWorkspaceMemberRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -17000,7 +17925,7 @@ type AddWorkspaceMemberResponse struct { func (x *AddWorkspaceMemberResponse) Reset() { *x = AddWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[220] + mi := &file_openshell_proto_msgTypes[231] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17012,7 +17937,7 @@ func (x *AddWorkspaceMemberResponse) String() string { func (*AddWorkspaceMemberResponse) ProtoMessage() {} func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[220] + mi := &file_openshell_proto_msgTypes[231] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17025,7 +17950,7 @@ func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{220} + return file_openshell_proto_rawDescGZIP(), []int{231} } func (x *AddWorkspaceMemberResponse) GetMember() *WorkspaceMember { @@ -17051,7 +17976,7 @@ type RemoveWorkspaceMemberRequest struct { func (x *RemoveWorkspaceMemberRequest) Reset() { *x = RemoveWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[221] + mi := &file_openshell_proto_msgTypes[232] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17063,7 +17988,7 @@ func (x *RemoveWorkspaceMemberRequest) String() string { func (*RemoveWorkspaceMemberRequest) ProtoMessage() {} func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[221] + mi := &file_openshell_proto_msgTypes[232] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17076,7 +18001,7 @@ func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{221} + return file_openshell_proto_rawDescGZIP(), []int{232} } func (x *RemoveWorkspaceMemberRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -17117,7 +18042,7 @@ type RemoveWorkspaceMemberResponse struct { func (x *RemoveWorkspaceMemberResponse) Reset() { *x = RemoveWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[222] + mi := &file_openshell_proto_msgTypes[233] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17129,7 +18054,7 @@ func (x *RemoveWorkspaceMemberResponse) String() string { func (*RemoveWorkspaceMemberResponse) ProtoMessage() {} func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[222] + mi := &file_openshell_proto_msgTypes[233] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17142,7 +18067,7 @@ func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{222} + return file_openshell_proto_rawDescGZIP(), []int{233} } func (x *RemoveWorkspaceMemberResponse) GetOutcome() DeletionOutcome { @@ -17169,7 +18094,7 @@ type ListWorkspaceMembersRequest struct { func (x *ListWorkspaceMembersRequest) Reset() { *x = ListWorkspaceMembersRequest{} - mi := &file_openshell_proto_msgTypes[223] + mi := &file_openshell_proto_msgTypes[234] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17181,7 +18106,7 @@ func (x *ListWorkspaceMembersRequest) String() string { func (*ListWorkspaceMembersRequest) ProtoMessage() {} func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[223] + mi := &file_openshell_proto_msgTypes[234] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17194,7 +18119,7 @@ func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersRequest.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{223} + return file_openshell_proto_rawDescGZIP(), []int{234} } func (x *ListWorkspaceMembersRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { @@ -17230,7 +18155,7 @@ type ListWorkspaceMembersResponse struct { func (x *ListWorkspaceMembersResponse) Reset() { *x = ListWorkspaceMembersResponse{} - mi := &file_openshell_proto_msgTypes[224] + mi := &file_openshell_proto_msgTypes[235] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17242,7 +18167,7 @@ func (x *ListWorkspaceMembersResponse) String() string { func (*ListWorkspaceMembersResponse) ProtoMessage() {} func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[224] + mi := &file_openshell_proto_msgTypes[235] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17255,7 +18180,7 @@ func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersResponse.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{224} + return file_openshell_proto_rawDescGZIP(), []int{235} } func (x *ListWorkspaceMembersResponse) GetMembers() []*WorkspaceMember { @@ -17290,7 +18215,7 @@ type ExtensionServiceCredential struct { func (x *ExtensionServiceCredential) Reset() { *x = ExtensionServiceCredential{} - mi := &file_openshell_proto_msgTypes[225] + mi := &file_openshell_proto_msgTypes[236] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17302,7 +18227,7 @@ func (x *ExtensionServiceCredential) String() string { func (*ExtensionServiceCredential) ProtoMessage() {} func (x *ExtensionServiceCredential) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[225] + mi := &file_openshell_proto_msgTypes[236] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17315,7 +18240,7 @@ func (x *ExtensionServiceCredential) ProtoReflect() protoreflect.Message { // Deprecated: Use ExtensionServiceCredential.ProtoReflect.Descriptor instead. func (*ExtensionServiceCredential) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{225} + return file_openshell_proto_rawDescGZIP(), []int{236} } func (x *ExtensionServiceCredential) GetServiceName() string { @@ -17352,7 +18277,7 @@ type EndpointObservation struct { func (x *EndpointObservation) Reset() { *x = EndpointObservation{} - mi := &file_openshell_proto_msgTypes[226] + mi := &file_openshell_proto_msgTypes[237] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17364,7 +18289,7 @@ func (x *EndpointObservation) String() string { func (*EndpointObservation) ProtoMessage() {} func (x *EndpointObservation) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[226] + mi := &file_openshell_proto_msgTypes[237] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17377,7 +18302,7 @@ func (x *EndpointObservation) ProtoReflect() protoreflect.Message { // Deprecated: Use EndpointObservation.ProtoReflect.Descriptor instead. func (*EndpointObservation) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{226} + return file_openshell_proto_rawDescGZIP(), []int{237} } func (x *EndpointObservation) GetEndpointId() string { @@ -17420,7 +18345,7 @@ type ReportEndpointStatusRequest struct { func (x *ReportEndpointStatusRequest) Reset() { *x = ReportEndpointStatusRequest{} - mi := &file_openshell_proto_msgTypes[227] + mi := &file_openshell_proto_msgTypes[238] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17432,7 +18357,7 @@ func (x *ReportEndpointStatusRequest) String() string { func (*ReportEndpointStatusRequest) ProtoMessage() {} func (x *ReportEndpointStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[227] + mi := &file_openshell_proto_msgTypes[238] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17445,7 +18370,7 @@ func (x *ReportEndpointStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportEndpointStatusRequest.ProtoReflect.Descriptor instead. func (*ReportEndpointStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{227} + return file_openshell_proto_rawDescGZIP(), []int{238} } func (x *ReportEndpointStatusRequest) GetSandboxId() string { @@ -17506,7 +18431,7 @@ type ReportEndpointStatusResponse struct { func (x *ReportEndpointStatusResponse) Reset() { *x = ReportEndpointStatusResponse{} - mi := &file_openshell_proto_msgTypes[228] + mi := &file_openshell_proto_msgTypes[239] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17518,7 +18443,7 @@ func (x *ReportEndpointStatusResponse) String() string { func (*ReportEndpointStatusResponse) ProtoMessage() {} func (x *ReportEndpointStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[228] + mi := &file_openshell_proto_msgTypes[239] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17531,7 +18456,7 @@ func (x *ReportEndpointStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportEndpointStatusResponse.ProtoReflect.Descriptor instead. func (*ReportEndpointStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{228} + return file_openshell_proto_rawDescGZIP(), []int{239} } // A configured endpoint and its last accepted network result in one record. @@ -17560,7 +18485,7 @@ type EndpointStatus struct { func (x *EndpointStatus) Reset() { *x = EndpointStatus{} - mi := &file_openshell_proto_msgTypes[229] + mi := &file_openshell_proto_msgTypes[240] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17572,7 +18497,7 @@ func (x *EndpointStatus) String() string { func (*EndpointStatus) ProtoMessage() {} func (x *EndpointStatus) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[229] + mi := &file_openshell_proto_msgTypes[240] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17585,7 +18510,7 @@ func (x *EndpointStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use EndpointStatus.ProtoReflect.Descriptor instead. func (*EndpointStatus) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{229} + return file_openshell_proto_rawDescGZIP(), []int{240} } func (x *EndpointStatus) GetEndpointId() string { @@ -17655,7 +18580,7 @@ type SandboxProvisioning struct { func (x *SandboxProvisioning) Reset() { *x = SandboxProvisioning{} - mi := &file_openshell_proto_msgTypes[230] + mi := &file_openshell_proto_msgTypes[241] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17667,7 +18592,7 @@ func (x *SandboxProvisioning) String() string { func (*SandboxProvisioning) ProtoMessage() {} func (x *SandboxProvisioning) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[230] + mi := &file_openshell_proto_msgTypes[241] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17680,7 +18605,7 @@ func (x *SandboxProvisioning) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxProvisioning.ProtoReflect.Descriptor instead. func (*SandboxProvisioning) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{230} + return file_openshell_proto_rawDescGZIP(), []int{241} } func (x *SandboxProvisioning) GetAttemptId() string { @@ -17775,7 +18700,7 @@ type SandboxServiceExposure struct { func (x *SandboxServiceExposure) Reset() { *x = SandboxServiceExposure{} - mi := &file_openshell_proto_msgTypes[231] + mi := &file_openshell_proto_msgTypes[242] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -17787,7 +18712,7 @@ func (x *SandboxServiceExposure) String() string { func (*SandboxServiceExposure) ProtoMessage() {} func (x *SandboxServiceExposure) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[231] + mi := &file_openshell_proto_msgTypes[242] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -17800,7 +18725,7 @@ func (x *SandboxServiceExposure) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxServiceExposure.ProtoReflect.Descriptor instead. func (*SandboxServiceExposure) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{231} + return file_openshell_proto_rawDescGZIP(), []int{242} } func (x *SandboxServiceExposure) GetService() string { @@ -18652,7 +19577,29 @@ const file_openshell_proto_rawDesc = "" + "\n" + "FilesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01J\x04\b\x03\x10\x04R\x18credential_expires_at_ms\"\xbd\x01\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01J\x04\b\x03\x10\x04R\x18credential_expires_at_ms\"\xe5\x02\n" + + "\x18ProviderEnvironmentValue\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1a\n" + + "\x05value\x18\x02 \x01(\tB\x04\x88\xb5\x18\x01R\x05value\x12\\\n" + + "\x0eclassification\x18\x04 \x01(\x0e24.openshell.v1.ProviderEnvironmentValueClassificationR\x0eclassification\x12a\n" + + "\x19static_credential_binding\x18\x05 \x01(\v2%.openshell.v1.StaticCredentialBindingR\x17staticCredentialBinding\x12C\n" + + "\x0fexpiration_time\x18g \x01(\v2\x1a.google.protobuf.TimestampR\x0eexpirationTimeJ\x04\b\x03\x10\x04R\rexpires_at_ms\"\xaa\x05\n" + + "\x1bProviderEnvironmentSnapshot\x122\n" + + "\x15provider_env_revision\x18\x01 \x01(\x04R\x13providerEnvRevision\x12>\n" + + "\x06values\x18\x02 \x03(\v2&.openshell.v1.ProviderEnvironmentValueR\x06values\x12r\n" + + "\x13dynamic_credentials\x18\x03 \x03(\v2A.openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntryR\x12dynamicCredentials\x12:\n" + + "\x19provider_attachment_epoch\x18\x04 \x01(\tR\x17providerAttachmentEpoch\x12\x1f\n" + + "\vpolicy_hash\x18\x05 \x01(\tR\n" + + "policyHash\x12P\n" + + "\x10readiness_reason\x18\x06 \x01(\x0e2%.openshell.v1.ProviderReadinessReasonR\x0freadinessReason\x12J\n" + + "\x05files\x18\a \x03(\v24.openshell.v1.ProviderEnvironmentSnapshot.FilesEntryR\x05files\x1an\n" + + "\x17DynamicCredentialsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12=\n" + + "\x05value\x18\x02 \x01(\v2'.openshell.v1.ProviderProfileCredentialR\x05value:\x028\x01\x1a8\n" + + "\n" + + "FilesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xbd\x01\n" + "#ExchangeProviderSubjectTokenRequest\x12\x1d\n" + "\n" + "sandbox_id\x18\x01 \x01(\tR\tsandboxId\x12\x1a\n" + @@ -18805,14 +19752,16 @@ const file_openshell_proto_rawDesc = "" + "\x17PushSandboxLogsResponse\"m\n" + "\x16GetSandboxLogsResponse\x120\n" + "\x04logs\x18\x01 \x03(\v2\x1c.openshell.v1.SandboxLogLineR\x04logs\x12!\n" + - "\fbuffer_total\x18\x02 \x01(\rR\vbufferTotal\"\xa2\x02\n" + + "\fbuffer_total\x18\x02 \x01(\rR\vbufferTotal\"\xd7\x03\n" + "\x11SupervisorMessage\x125\n" + "\x05hello\x18\x01 \x01(\v2\x1d.openshell.v1.SupervisorHelloH\x00R\x05hello\x12A\n" + "\theartbeat\x18\x02 \x01(\v2!.openshell.v1.SupervisorHeartbeatH\x00R\theartbeat\x12K\n" + "\x11relay_open_result\x18\x03 \x01(\v2\x1d.openshell.v1.RelayOpenResultH\x00R\x0frelayOpenResult\x12;\n" + "\vrelay_close\x18\x04 \x01(\v2\x18.openshell.v1.RelayCloseH\x00R\n" + - "relayCloseB\t\n" + - "\apayload\"\xea\x02\n" + + "relayClose\x12T\n" + + "\x14config_update_result\x18\x05 \x01(\v2 .openshell.v1.ConfigUpdateResultH\x00R\x12configUpdateResult\x12]\n" + + "\x17config_bootstrap_result\x18\x06 \x01(\v2#.openshell.v1.ConfigBootstrapResultH\x00R\x15configBootstrapResultB\t\n" + + "\apayload\"\xad\x03\n" + "\x0eGatewayMessage\x12J\n" + "\x10session_accepted\x18\x01 \x01(\v2\x1d.openshell.v1.SessionAcceptedH\x00R\x0fsessionAccepted\x12J\n" + "\x10session_rejected\x18\x02 \x01(\v2\x1d.openshell.v1.SessionRejectedH\x00R\x0fsessionRejected\x12>\n" + @@ -18820,19 +19769,48 @@ const file_openshell_proto_rawDesc = "" + "\n" + "relay_open\x18\x04 \x01(\v2\x17.openshell.v1.RelayOpenH\x00R\trelayOpen\x12;\n" + "\vrelay_close\x18\x05 \x01(\v2\x18.openshell.v1.RelayCloseH\x00R\n" + - "relayCloseB\t\n" + - "\apayload\"\xbc\x01\n" + + "relayClose\x12A\n" + + "\rconfig_update\x18\x06 \x01(\v2\x1a.openshell.v1.ConfigUpdateH\x00R\fconfigUpdateB\t\n" + + "\apayload\"\xe9\x01\n" + "\x0fSupervisorHello\x12\x1d\n" + "\n" + "sandbox_id\x18\x01 \x01(\tR\tsandboxId\x12\x1f\n" + "\vinstance_id\x18\x02 \x01(\tR\n" + "instanceId\x12)\n" + "\x10connection_epoch\x18\x03 \x01(\x04R\x0fconnectionEpoch\x12>\n" + - "\x1bsupports_provider_readiness\x18\x04 \x01(\bR\x19supportsProviderReadiness\"\x99\x01\n" + + "\x1bsupports_provider_readiness\x18\x04 \x01(\bR\x19supportsProviderReadiness\x12+\n" + + "\x11protocol_revision\x18\x05 \x01(\rR\x10protocolRevision\"\x83\x02\n" + "\x0fSessionAccepted\x12\x1d\n" + "\n" + - "session_id\x18\x01 \x01(\tR\tsessionId\x12H\n" + - "\x12heartbeat_interval\x18f \x01(\v2\x19.google.protobuf.DurationR\x11heartbeatIntervalJ\x04\b\x02\x10\x03R\x17heartbeat_interval_secs\")\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12;\n" + + "\tbootstrap\x18\x03 \x01(\v2\x1d.openshell.v1.ConfigBootstrapR\tbootstrap\x12+\n" + + "\x11protocol_revision\x18\x04 \x01(\rR\x10protocolRevision\x12H\n" + + "\x12heartbeat_interval\x18f \x01(\v2\x19.google.protobuf.DurationR\x11heartbeatIntervalJ\x04\b\x02\x10\x03R\x17heartbeat_interval_secs\"\xc3\x01\n" + + "\x0fConfigBootstrap\x12R\n" + + "\x0esandbox_config\x18\x01 \x01(\v2+.openshell.sandbox.v1.SandboxConfigSnapshotR\rsandboxConfig\x12\\\n" + + "\x14provider_environment\x18\x02 \x01(\v2).openshell.v1.ProviderEnvironmentSnapshotR\x13providerEnvironment\"\x9d\x02\n" + + "\fConfigUpdate\x12\x1b\n" + + "\tupdate_id\x18\x01 \x01(\tR\bupdateId\x12-\n" + + "\x12component_sequence\x18\x02 \x01(\x04R\x11componentSequence\x12T\n" + + "\x0esandbox_config\x18\x03 \x01(\v2+.openshell.sandbox.v1.SandboxConfigSnapshotH\x00R\rsandboxConfig\x12^\n" + + "\x14provider_environment\x18\x04 \x01(\v2).openshell.v1.ProviderEnvironmentSnapshotH\x00R\x13providerEnvironmentB\v\n" + + "\tcomponent\"`\n" + + "\x12ConfigApplyFailure\x12\x12\n" + + "\x04code\x18\x01 \x01(\tR\x04code\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12\x1c\n" + + "\tretryable\x18\x03 \x01(\bR\tretryable\"\xf7\x02\n" + + "\x1aConfigComponentApplyResult\x12;\n" + + "\tcomponent\x18\x01 \x01(\x0e2\x1d.openshell.v1.ConfigComponentR\tcomponent\x12S\n" + + "\x12requested_revision\x18\x02 \x01(\v2$.openshell.v1.ConfigSnapshotRevisionR\x11requestedRevision\x12O\n" + + "\x10applied_revision\x18\x03 \x01(\v2$.openshell.v1.ConfigSnapshotRevisionR\x0fappliedRevision\x12:\n" + + "\aoutcome\x18\x04 \x01(\x0e2 .openshell.v1.ConfigApplyOutcomeR\aoutcome\x12:\n" + + "\afailure\x18\x05 \x01(\v2 .openshell.v1.ConfigApplyFailureR\afailure\"\xa2\x01\n" + + "\x12ConfigUpdateResult\x12\x1b\n" + + "\tupdate_id\x18\x01 \x01(\tR\bupdateId\x12-\n" + + "\x12component_sequence\x18\x02 \x01(\x04R\x11componentSequence\x12@\n" + + "\x06result\x18\x03 \x01(\v2(.openshell.v1.ConfigComponentApplyResultR\x06result\"[\n" + + "\x15ConfigBootstrapResult\x12B\n" + + "\aresults\x18\x01 \x03(\v2(.openshell.v1.ConfigComponentApplyResultR\aresults\")\n" + "\x0fSessionRejected\x12\x16\n" + "\x06reason\x18\x01 \x01(\tR\x06reason\"\x15\n" + "\x13SupervisorHeartbeat\"\x12\n" + @@ -18879,7 +19857,24 @@ const file_openshell_proto_rawDesc = "" + "\x0ePeerRelayFrame\x121\n" + "\x04init\x18\x01 \x01(\v2\x1b.openshell.v1.PeerRelayInitH\x00R\x04init\x12\x14\n" + "\x04data\x18\x02 \x01(\fH\x00R\x04dataB\t\n" + - "\apayload\"`\n" + + "\apayload\"W\n" + + "\x17PeerConfigSandboxTarget\x12\x1d\n" + + "\n" + + "sandbox_id\x18\x01 \x01(\tR\tsandboxId\x12\x1d\n" + + "\n" + + "session_id\x18\x02 \x01(\tR\tsessionId\"\x8a\x02\n" + + "\x1bPeerConfigUpdateHintRequest\x12A\n" + + "\asandbox\x18\x01 \x01(\v2%.openshell.v1.PeerConfigSandboxTargetH\x00R\asandbox\x12\x1e\n" + + "\tworkspace\x18\x02 \x01(\tH\x00R\tworkspace\x12%\n" + + "\rall_connected\x18\x03 \x01(\bH\x00R\fallConnected\x12%\n" + + "\x0esandbox_config\x18\x04 \x01(\bR\rsandboxConfig\x121\n" + + "\x14provider_environment\x18\x05 \x01(\bR\x13providerEnvironmentB\a\n" + + "\x05scope\"^\n" + + "\x1cPeerConfigUpdateHintResponse\x12\x1f\n" + + "\vstale_owner\x18\x01 \x01(\bR\n" + + "staleOwner\x12\x1d\n" + + "\n" + + "queue_full\x18\x02 \x01(\bR\tqueueFull\"`\n" + "\x0fRelayOpenResult\x12\x1d\n" + "\n" + "channel_id\x18\x01 \x01(\tR\tchannelId\x12\x18\n" + @@ -19255,7 +20250,11 @@ const file_openshell_proto_rawDesc = "" + "(PROVIDER_PROFILE_CATEGORY_SOURCE_CONTROL\x10\x04\x12'\n" + "#PROVIDER_PROFILE_CATEGORY_MESSAGING\x10\x05\x12\"\n" + "\x1ePROVIDER_PROFILE_CATEGORY_DATA\x10\x06\x12'\n" + - "#PROVIDER_PROFILE_CATEGORY_KNOWLEDGE\x10\a*\xcf\x01\n" + + "#PROVIDER_PROFILE_CATEGORY_KNOWLEDGE\x10\a*\xde\x01\n" + + "&ProviderEnvironmentValueClassification\x129\n" + + "5PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_UNSPECIFIED\x10\x00\x128\n" + + "4PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_NON_SECRET\x10\x01\x12?\n" + + ";PROVIDER_ENVIRONMENT_VALUE_CLASSIFICATION_STATIC_CREDENTIAL\x10\x02*\xcf\x01\n" + "\x1bConfigurationAdmissionState\x12-\n" + ")CONFIGURATION_ADMISSION_STATE_UNSPECIFIED\x10\x00\x12)\n" + "%CONFIGURATION_ADMISSION_STATE_PENDING\x10\x01\x12*\n" + @@ -19304,7 +20303,7 @@ const file_openshell_proto_rawDesc = "" + "\x18ServiceAuthorizationMode\x12*\n" + "&SERVICE_AUTHORIZATION_MODE_UNSPECIFIED\x10\x00\x12$\n" + " SERVICE_AUTHORIZATION_MODE_STRIP\x10\x01\x121\n" + - "-SERVICE_AUTHORIZATION_MODE_BEARER_PASSTHROUGH\x10\x022\xafU\n" + + "-SERVICE_AUTHORIZATION_MODE_BEARER_PASSTHROUGH\x10\x022\xacV\n" + "\tOpenShell\x12Z\n" + "\x06Health\x12\x1b.openshell.v1.HealthRequest\x1a\x1c.openshell.v1.HealthResponse\"\x15\x82\xb5\x18\x11\n" + "\x0funauthenticated\x12i\n" + @@ -19438,6 +20437,9 @@ const file_openshell_proto_rawDesc = "" + "\x04peer\x12\x89\x01\n" + "\x1cPeerGetSandboxProviderStatus\x12-.openshell.v1.GetSandboxProviderStatusRequest\x1a..openshell.v1.GetSandboxProviderStatusResponse\"\n" + "\x82\xb5\x18\x06\n" + + "\x04peer\x12{\n" + + "\x16PeerNotifyConfigUpdate\x12).openshell.v1.PeerConfigUpdateHintRequest\x1a*.openshell.v1.PeerConfigUpdateHintResponse\"\n" + + "\x82\xb5\x18\x06\n" + "\x04peer\x12w\n" + "\fWatchSandbox\x12!.openshell.v1.WatchSandboxRequest\x1a .openshell.v1.SandboxStreamEvent\" \x82\xb5\x18\x1c\n" + "\x06bearer\x12\x04user\"\fsandbox:read0\x01\x12|\n" + @@ -19490,8 +20492,8 @@ func file_openshell_proto_rawDescGZIP() []byte { return file_openshell_proto_rawDescData } -var file_openshell_proto_enumTypes = make([]protoimpl.EnumInfo, 20) -var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 255) +var file_openshell_proto_enumTypes = make([]protoimpl.EnumInfo, 21) +var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 268) var file_openshell_proto_goTypes = []any{ (ExtensionKind)(0), // 0: openshell.v1.ExtensionKind (SandboxPhase)(0), // 1: openshell.v1.SandboxPhase @@ -19504,784 +20506,825 @@ var file_openshell_proto_goTypes = []any{ (ProviderCredentialTokenGrantType)(0), // 8: openshell.v1.ProviderCredentialTokenGrantType (ProviderCredentialRefreshStrategy)(0), // 9: openshell.v1.ProviderCredentialRefreshStrategy (ProviderProfileCategory)(0), // 10: openshell.v1.ProviderProfileCategory - (ConfigurationAdmissionState)(0), // 11: openshell.v1.ConfigurationAdmissionState - (PolicyStatus)(0), // 12: openshell.v1.PolicyStatus - (ServiceStatus)(0), // 13: openshell.v1.ServiceStatus - (WorkspaceRole)(0), // 14: openshell.v1.WorkspaceRole - (ProviderCredentialRefreshRecoveryAction)(0), // 15: openshell.v1.ProviderCredentialRefreshRecoveryAction - (SandboxRestartPolicy)(0), // 16: openshell.v1.SandboxRestartPolicy - (DeletionOutcome)(0), // 17: openshell.v1.DeletionOutcome - (EndpointResult)(0), // 18: openshell.v1.EndpointResult - (ServiceAuthorizationMode)(0), // 19: openshell.v1.ServiceAuthorizationMode - (*IssueSandboxTokenRequest)(nil), // 20: openshell.v1.IssueSandboxTokenRequest - (*IssueSandboxTokenResponse)(nil), // 21: openshell.v1.IssueSandboxTokenResponse - (*RefreshSandboxTokenRequest)(nil), // 22: openshell.v1.RefreshSandboxTokenRequest - (*RefreshSandboxTokenResponse)(nil), // 23: openshell.v1.RefreshSandboxTokenResponse - (*HealthRequest)(nil), // 24: openshell.v1.HealthRequest - (*HealthResponse)(nil), // 25: openshell.v1.HealthResponse - (*GetCurrentUserRequest)(nil), // 26: openshell.v1.GetCurrentUserRequest - (*GetCurrentUserResponse)(nil), // 27: openshell.v1.GetCurrentUserResponse - (*GetGatewayInfoRequest)(nil), // 28: openshell.v1.GetGatewayInfoRequest - (*GetGatewayInfoResponse)(nil), // 29: openshell.v1.GetGatewayInfoResponse - (*NegotiatedExtensionInfo)(nil), // 30: openshell.v1.NegotiatedExtensionInfo - (*ComputeDriverInfo)(nil), // 31: openshell.v1.ComputeDriverInfo - (*ComputeDriverCapabilities)(nil), // 32: openshell.v1.ComputeDriverCapabilities - (*ResourceCapabilities)(nil), // 33: openshell.v1.ResourceCapabilities - (*CpuResourceCapabilities)(nil), // 34: openshell.v1.CpuResourceCapabilities - (*MemoryResourceCapabilities)(nil), // 35: openshell.v1.MemoryResourceCapabilities - (*GpuResourceCapabilities)(nil), // 36: openshell.v1.GpuResourceCapabilities - (*Sandbox)(nil), // 37: openshell.v1.Sandbox - (*SandboxSpec)(nil), // 38: openshell.v1.SandboxSpec - (*ResourceRequirements)(nil), // 39: openshell.v1.ResourceRequirements - (*GpuResourceRequirements)(nil), // 40: openshell.v1.GpuResourceRequirements - (*SandboxTemplate)(nil), // 41: openshell.v1.SandboxTemplate - (*SandboxWorkloadTemplate)(nil), // 42: openshell.v1.SandboxWorkloadTemplate - (*SandboxWorkloadTemplateSpec)(nil), // 43: openshell.v1.SandboxWorkloadTemplateSpec - (*SandboxWorkloadConfig)(nil), // 44: openshell.v1.SandboxWorkloadConfig - (*SandboxResources)(nil), // 45: openshell.v1.SandboxResources - (*SandboxServiceLevel)(nil), // 46: openshell.v1.SandboxServiceLevel - (*SandboxStartup)(nil), // 47: openshell.v1.SandboxStartup - (*SandboxWorkloadTemplateProvenance)(nil), // 48: openshell.v1.SandboxWorkloadTemplateProvenance - (*SandboxStatus)(nil), // 49: openshell.v1.SandboxStatus - (*SandboxCondition)(nil), // 50: openshell.v1.SandboxCondition - (*PlatformEvent)(nil), // 51: openshell.v1.PlatformEvent - (*CreateSandboxRequest)(nil), // 52: openshell.v1.CreateSandboxRequest - (*CreateSandboxTemplateRequest)(nil), // 53: openshell.v1.CreateSandboxTemplateRequest - (*GetSandboxTemplateRequest)(nil), // 54: openshell.v1.GetSandboxTemplateRequest - (*ListSandboxTemplatesRequest)(nil), // 55: openshell.v1.ListSandboxTemplatesRequest - (*DeleteSandboxTemplateRequest)(nil), // 56: openshell.v1.DeleteSandboxTemplateRequest - (*SandboxTemplateResponse)(nil), // 57: openshell.v1.SandboxTemplateResponse - (*ListSandboxTemplatesResponse)(nil), // 58: openshell.v1.ListSandboxTemplatesResponse - (*DeleteSandboxTemplateResponse)(nil), // 59: openshell.v1.DeleteSandboxTemplateResponse - (*BeginRootfsTarStagingRequest)(nil), // 60: openshell.v1.BeginRootfsTarStagingRequest - (*BeginRootfsTarStagingResponse)(nil), // 61: openshell.v1.BeginRootfsTarStagingResponse - (*GetSandboxRequest)(nil), // 62: openshell.v1.GetSandboxRequest - (*ListSandboxesRequest)(nil), // 63: openshell.v1.ListSandboxesRequest - (*ListSandboxProvidersRequest)(nil), // 64: openshell.v1.ListSandboxProvidersRequest - (*AttachSandboxProviderRequest)(nil), // 65: openshell.v1.AttachSandboxProviderRequest - (*DetachSandboxProviderRequest)(nil), // 66: openshell.v1.DetachSandboxProviderRequest - (*DeleteSandboxRequest)(nil), // 67: openshell.v1.DeleteSandboxRequest - (*StopSandboxRequest)(nil), // 68: openshell.v1.StopSandboxRequest - (*StartSandboxRequest)(nil), // 69: openshell.v1.StartSandboxRequest - (*SandboxResponse)(nil), // 70: openshell.v1.SandboxResponse - (*ListSandboxesResponse)(nil), // 71: openshell.v1.ListSandboxesResponse - (*ListSandboxProvidersResponse)(nil), // 72: openshell.v1.ListSandboxProvidersResponse - (*AttachSandboxProviderResponse)(nil), // 73: openshell.v1.AttachSandboxProviderResponse - (*DetachSandboxProviderResponse)(nil), // 74: openshell.v1.DetachSandboxProviderResponse - (*ProviderDesiredIdentity)(nil), // 75: openshell.v1.ProviderDesiredIdentity - (*ConfigSnapshotRevision)(nil), // 76: openshell.v1.ConfigSnapshotRevision - (*SandboxConfigRevision)(nil), // 77: openshell.v1.SandboxConfigRevision - (*ConfigUpdateOperation)(nil), // 78: openshell.v1.ConfigUpdateOperation - (*ProviderMutationReceipt)(nil), // 79: openshell.v1.ProviderMutationReceipt - (*ProviderReadinessObservation)(nil), // 80: openshell.v1.ProviderReadinessObservation - (*ProviderReadinessStatus)(nil), // 81: openshell.v1.ProviderReadinessStatus - (*GetSandboxProviderStatusRequest)(nil), // 82: openshell.v1.GetSandboxProviderStatusRequest - (*GetSandboxProviderStatusResponse)(nil), // 83: openshell.v1.GetSandboxProviderStatusResponse - (*ReportProviderReadinessRequest)(nil), // 84: openshell.v1.ReportProviderReadinessRequest - (*ReportProviderReadinessResponse)(nil), // 85: openshell.v1.ReportProviderReadinessResponse - (*DeleteSandboxResponse)(nil), // 86: openshell.v1.DeleteSandboxResponse - (*CreateSshSessionRequest)(nil), // 87: openshell.v1.CreateSshSessionRequest - (*CreateSshSessionResponse)(nil), // 88: openshell.v1.CreateSshSessionResponse - (*ExposeServiceRequest)(nil), // 89: openshell.v1.ExposeServiceRequest - (*GetServiceRequest)(nil), // 90: openshell.v1.GetServiceRequest - (*ListServicesRequest)(nil), // 91: openshell.v1.ListServicesRequest - (*ListServicesResponse)(nil), // 92: openshell.v1.ListServicesResponse - (*DeleteServiceRequest)(nil), // 93: openshell.v1.DeleteServiceRequest - (*DeleteServiceResponse)(nil), // 94: openshell.v1.DeleteServiceResponse - (*ServiceEndpoint)(nil), // 95: openshell.v1.ServiceEndpoint - (*ServiceEndpointResponse)(nil), // 96: openshell.v1.ServiceEndpointResponse - (*RevokeSshSessionRequest)(nil), // 97: openshell.v1.RevokeSshSessionRequest - (*RevokeSshSessionResponse)(nil), // 98: openshell.v1.RevokeSshSessionResponse - (*ExecSandboxRequest)(nil), // 99: openshell.v1.ExecSandboxRequest - (*ExecSandboxStdout)(nil), // 100: openshell.v1.ExecSandboxStdout - (*ExecSandboxStderr)(nil), // 101: openshell.v1.ExecSandboxStderr - (*ExecSandboxExit)(nil), // 102: openshell.v1.ExecSandboxExit - (*ExecSandboxEvent)(nil), // 103: openshell.v1.ExecSandboxEvent - (*TcpForwardInit)(nil), // 104: openshell.v1.TcpForwardInit - (*TcpForwardFrame)(nil), // 105: openshell.v1.TcpForwardFrame - (*ExecSandboxInput)(nil), // 106: openshell.v1.ExecSandboxInput - (*ExecSandboxWindowResize)(nil), // 107: openshell.v1.ExecSandboxWindowResize - (*SshSession)(nil), // 108: openshell.v1.SshSession - (*WatchSandboxRequest)(nil), // 109: openshell.v1.WatchSandboxRequest - (*SandboxStreamEvent)(nil), // 110: openshell.v1.SandboxStreamEvent - (*SandboxLogLine)(nil), // 111: openshell.v1.SandboxLogLine - (*SandboxStreamWarning)(nil), // 112: openshell.v1.SandboxStreamWarning - (*CreateProviderRequest)(nil), // 113: openshell.v1.CreateProviderRequest - (*GetProviderRequest)(nil), // 114: openshell.v1.GetProviderRequest - (*ListProvidersRequest)(nil), // 115: openshell.v1.ListProvidersRequest - (*UpdateProviderRequest)(nil), // 116: openshell.v1.UpdateProviderRequest - (*DeleteProviderRequest)(nil), // 117: openshell.v1.DeleteProviderRequest - (*ProviderResponse)(nil), // 118: openshell.v1.ProviderResponse - (*ListProvidersResponse)(nil), // 119: openshell.v1.ListProvidersResponse - (*ListProviderProfilesRequest)(nil), // 120: openshell.v1.ListProviderProfilesRequest - (*GetProviderProfileRequest)(nil), // 121: openshell.v1.GetProviderProfileRequest - (*ProviderProfileImportItem)(nil), // 122: openshell.v1.ProviderProfileImportItem - (*ProviderProfileDiagnostic)(nil), // 123: openshell.v1.ProviderProfileDiagnostic - (*ProviderCredentialTokenGrantAudienceOverride)(nil), // 124: openshell.v1.ProviderCredentialTokenGrantAudienceOverride - (*ProviderCredentialTokenGrantSubjectToken)(nil), // 125: openshell.v1.ProviderCredentialTokenGrantSubjectToken - (*ProviderCredentialTokenGrant)(nil), // 126: openshell.v1.ProviderCredentialTokenGrant - (*ProviderProfileCredential)(nil), // 127: openshell.v1.ProviderProfileCredential - (*ProviderCredentialRefreshMaterial)(nil), // 128: openshell.v1.ProviderCredentialRefreshMaterial - (*ProviderCredentialRefreshOutput)(nil), // 129: openshell.v1.ProviderCredentialRefreshOutput - (*ProviderCredentialRefresh)(nil), // 130: openshell.v1.ProviderCredentialRefresh - (*ProviderCredentialRefreshStatus)(nil), // 131: openshell.v1.ProviderCredentialRefreshStatus - (*ProviderProfileDiscovery)(nil), // 132: openshell.v1.ProviderProfileDiscovery - (*GetProviderRefreshStatusRequest)(nil), // 133: openshell.v1.GetProviderRefreshStatusRequest - (*GetProviderRefreshStatusResponse)(nil), // 134: openshell.v1.GetProviderRefreshStatusResponse - (*ConfigureProviderRefreshRequest)(nil), // 135: openshell.v1.ConfigureProviderRefreshRequest - (*ConfigureProviderRefreshResponse)(nil), // 136: openshell.v1.ConfigureProviderRefreshResponse - (*RotateProviderCredentialRequest)(nil), // 137: openshell.v1.RotateProviderCredentialRequest - (*RotateProviderCredentialResponse)(nil), // 138: openshell.v1.RotateProviderCredentialResponse - (*DeleteProviderRefreshRequest)(nil), // 139: openshell.v1.DeleteProviderRefreshRequest - (*DeleteProviderRefreshResponse)(nil), // 140: openshell.v1.DeleteProviderRefreshResponse - (*ProviderProfile)(nil), // 141: openshell.v1.ProviderProfile - (*ProviderProfileFile)(nil), // 142: openshell.v1.ProviderProfileFile - (*ProviderProfileResponse)(nil), // 143: openshell.v1.ProviderProfileResponse - (*ListProviderProfilesResponse)(nil), // 144: openshell.v1.ListProviderProfilesResponse - (*ImportProviderProfilesRequest)(nil), // 145: openshell.v1.ImportProviderProfilesRequest - (*ImportProviderProfilesResponse)(nil), // 146: openshell.v1.ImportProviderProfilesResponse - (*UpdateProviderProfilesRequest)(nil), // 147: openshell.v1.UpdateProviderProfilesRequest - (*UpdateProviderProfilesResponse)(nil), // 148: openshell.v1.UpdateProviderProfilesResponse - (*LintProviderProfilesRequest)(nil), // 149: openshell.v1.LintProviderProfilesRequest - (*LintProviderProfilesResponse)(nil), // 150: openshell.v1.LintProviderProfilesResponse - (*DeleteProviderResponse)(nil), // 151: openshell.v1.DeleteProviderResponse - (*DeleteProviderProfileRequest)(nil), // 152: openshell.v1.DeleteProviderProfileRequest - (*DeleteProviderProfileResponse)(nil), // 153: openshell.v1.DeleteProviderProfileResponse - (*GetSandboxProviderEnvironmentRequest)(nil), // 154: openshell.v1.GetSandboxProviderEnvironmentRequest - (*StaticCredentialEndpointBinding)(nil), // 155: openshell.v1.StaticCredentialEndpointBinding - (*StaticCredentialBinding)(nil), // 156: openshell.v1.StaticCredentialBinding - (*GetSandboxProviderEnvironmentResponse)(nil), // 157: openshell.v1.GetSandboxProviderEnvironmentResponse - (*ExchangeProviderSubjectTokenRequest)(nil), // 158: openshell.v1.ExchangeProviderSubjectTokenRequest - (*ExchangeProviderSubjectTokenResponse)(nil), // 159: openshell.v1.ExchangeProviderSubjectTokenResponse - (*UpdateConfigRequest)(nil), // 160: openshell.v1.UpdateConfigRequest - (*PolicyMergeOperation)(nil), // 161: openshell.v1.PolicyMergeOperation - (*AddNetworkRule)(nil), // 162: openshell.v1.AddNetworkRule - (*RemoveNetworkEndpoint)(nil), // 163: openshell.v1.RemoveNetworkEndpoint - (*RemoveNetworkRule)(nil), // 164: openshell.v1.RemoveNetworkRule - (*L7RuleTarget)(nil), // 165: openshell.v1.L7RuleTarget - (*AddDenyRules)(nil), // 166: openshell.v1.AddDenyRules - (*AddAllowRules)(nil), // 167: openshell.v1.AddAllowRules - (*RemoveNetworkBinary)(nil), // 168: openshell.v1.RemoveNetworkBinary - (*UpdateConfigResponse)(nil), // 169: openshell.v1.UpdateConfigResponse - (*GetSandboxPolicyStatusRequest)(nil), // 170: openshell.v1.GetSandboxPolicyStatusRequest - (*GetSandboxPolicyStatusResponse)(nil), // 171: openshell.v1.GetSandboxPolicyStatusResponse - (*ListSandboxPoliciesRequest)(nil), // 172: openshell.v1.ListSandboxPoliciesRequest - (*ListSandboxPoliciesResponse)(nil), // 173: openshell.v1.ListSandboxPoliciesResponse - (*ReportPolicyStatusRequest)(nil), // 174: openshell.v1.ReportPolicyStatusRequest - (*ReportPolicyStatusResponse)(nil), // 175: openshell.v1.ReportPolicyStatusResponse - (*SandboxConfigurationAdmission)(nil), // 176: openshell.v1.SandboxConfigurationAdmission - (*ReportSandboxConfigurationRequest)(nil), // 177: openshell.v1.ReportSandboxConfigurationRequest - (*ReportSandboxConfigurationResponse)(nil), // 178: openshell.v1.ReportSandboxConfigurationResponse - (*SandboxPolicyRevision)(nil), // 179: openshell.v1.SandboxPolicyRevision - (*GetSandboxLogsRequest)(nil), // 180: openshell.v1.GetSandboxLogsRequest - (*PushSandboxLogsRequest)(nil), // 181: openshell.v1.PushSandboxLogsRequest - (*PushSandboxLogsResponse)(nil), // 182: openshell.v1.PushSandboxLogsResponse - (*GetSandboxLogsResponse)(nil), // 183: openshell.v1.GetSandboxLogsResponse - (*SupervisorMessage)(nil), // 184: openshell.v1.SupervisorMessage - (*GatewayMessage)(nil), // 185: openshell.v1.GatewayMessage - (*SupervisorHello)(nil), // 186: openshell.v1.SupervisorHello - (*SessionAccepted)(nil), // 187: openshell.v1.SessionAccepted - (*SessionRejected)(nil), // 188: openshell.v1.SessionRejected - (*SupervisorHeartbeat)(nil), // 189: openshell.v1.SupervisorHeartbeat - (*GatewayHeartbeat)(nil), // 190: openshell.v1.GatewayHeartbeat - (*ReportMainProcessExitRequest)(nil), // 191: openshell.v1.ReportMainProcessExitRequest - (*ReportMainProcessExitResponse)(nil), // 192: openshell.v1.ReportMainProcessExitResponse - (*FinalizeMainProcessExitRequest)(nil), // 193: openshell.v1.FinalizeMainProcessExitRequest - (*FinalizeMainProcessExitResponse)(nil), // 194: openshell.v1.FinalizeMainProcessExitResponse - (*RelayOpen)(nil), // 195: openshell.v1.RelayOpen - (*SshRelayTarget)(nil), // 196: openshell.v1.SshRelayTarget - (*TcpRelayTarget)(nil), // 197: openshell.v1.TcpRelayTarget - (*RelayInit)(nil), // 198: openshell.v1.RelayInit - (*RelayFrame)(nil), // 199: openshell.v1.RelayFrame - (*PeerRelayInit)(nil), // 200: openshell.v1.PeerRelayInit - (*PeerRelayFrame)(nil), // 201: openshell.v1.PeerRelayFrame - (*RelayOpenResult)(nil), // 202: openshell.v1.RelayOpenResult - (*RelayClose)(nil), // 203: openshell.v1.RelayClose - (*L7RequestSample)(nil), // 204: openshell.v1.L7RequestSample - (*DenialSummary)(nil), // 205: openshell.v1.DenialSummary - (*DenialGroupCount)(nil), // 206: openshell.v1.DenialGroupCount - (*NetworkActivitySummary)(nil), // 207: openshell.v1.NetworkActivitySummary - (*PolicyChunk)(nil), // 208: openshell.v1.PolicyChunk - (*DraftPolicyUpdate)(nil), // 209: openshell.v1.DraftPolicyUpdate - (*SubmitPolicyAnalysisRequest)(nil), // 210: openshell.v1.SubmitPolicyAnalysisRequest - (*SubmitPolicyAnalysisResponse)(nil), // 211: openshell.v1.SubmitPolicyAnalysisResponse - (*GetDraftPolicyRequest)(nil), // 212: openshell.v1.GetDraftPolicyRequest - (*GetDraftPolicyResponse)(nil), // 213: openshell.v1.GetDraftPolicyResponse - (*ApproveDraftChunkRequest)(nil), // 214: openshell.v1.ApproveDraftChunkRequest - (*ApproveDraftChunkResponse)(nil), // 215: openshell.v1.ApproveDraftChunkResponse - (*RejectDraftChunkRequest)(nil), // 216: openshell.v1.RejectDraftChunkRequest - (*RejectDraftChunkResponse)(nil), // 217: openshell.v1.RejectDraftChunkResponse - (*DraftChunkApproval)(nil), // 218: openshell.v1.DraftChunkApproval - (*ApproveAllDraftChunksRequest)(nil), // 219: openshell.v1.ApproveAllDraftChunksRequest - (*ApproveAllDraftChunksResponse)(nil), // 220: openshell.v1.ApproveAllDraftChunksResponse - (*EditDraftChunkRequest)(nil), // 221: openshell.v1.EditDraftChunkRequest - (*EditDraftChunkResponse)(nil), // 222: openshell.v1.EditDraftChunkResponse - (*UndoDraftChunkRequest)(nil), // 223: openshell.v1.UndoDraftChunkRequest - (*UndoDraftChunkResponse)(nil), // 224: openshell.v1.UndoDraftChunkResponse - (*ClearDraftChunksRequest)(nil), // 225: openshell.v1.ClearDraftChunksRequest - (*ClearDraftChunksResponse)(nil), // 226: openshell.v1.ClearDraftChunksResponse - (*GetDraftHistoryRequest)(nil), // 227: openshell.v1.GetDraftHistoryRequest - (*DraftHistoryEntry)(nil), // 228: openshell.v1.DraftHistoryEntry - (*GetDraftHistoryResponse)(nil), // 229: openshell.v1.GetDraftHistoryResponse - (*CreateWorkspaceRequest)(nil), // 230: openshell.v1.CreateWorkspaceRequest - (*CreateWorkspaceResponse)(nil), // 231: openshell.v1.CreateWorkspaceResponse - (*GetWorkspaceRequest)(nil), // 232: openshell.v1.GetWorkspaceRequest - (*GetWorkspaceResponse)(nil), // 233: openshell.v1.GetWorkspaceResponse - (*ListWorkspacesRequest)(nil), // 234: openshell.v1.ListWorkspacesRequest - (*ListWorkspacesResponse)(nil), // 235: openshell.v1.ListWorkspacesResponse - (*DeleteWorkspaceRequest)(nil), // 236: openshell.v1.DeleteWorkspaceRequest - (*DeleteWorkspaceResponse)(nil), // 237: openshell.v1.DeleteWorkspaceResponse - (*WorkspaceMember)(nil), // 238: openshell.v1.WorkspaceMember - (*AddWorkspaceMemberRequest)(nil), // 239: openshell.v1.AddWorkspaceMemberRequest - (*AddWorkspaceMemberResponse)(nil), // 240: openshell.v1.AddWorkspaceMemberResponse - (*RemoveWorkspaceMemberRequest)(nil), // 241: openshell.v1.RemoveWorkspaceMemberRequest - (*RemoveWorkspaceMemberResponse)(nil), // 242: openshell.v1.RemoveWorkspaceMemberResponse - (*ListWorkspaceMembersRequest)(nil), // 243: openshell.v1.ListWorkspaceMembersRequest - (*ListWorkspaceMembersResponse)(nil), // 244: openshell.v1.ListWorkspaceMembersResponse - (*ExtensionServiceCredential)(nil), // 245: openshell.v1.ExtensionServiceCredential - (*EndpointObservation)(nil), // 246: openshell.v1.EndpointObservation - (*ReportEndpointStatusRequest)(nil), // 247: openshell.v1.ReportEndpointStatusRequest - (*ReportEndpointStatusResponse)(nil), // 248: openshell.v1.ReportEndpointStatusResponse - (*EndpointStatus)(nil), // 249: openshell.v1.EndpointStatus - (*SandboxProvisioning)(nil), // 250: openshell.v1.SandboxProvisioning - (*SandboxServiceExposure)(nil), // 251: openshell.v1.SandboxServiceExposure - nil, // 252: openshell.v1.SandboxSpec.EnvironmentEntry - nil, // 253: openshell.v1.SandboxTemplate.LabelsEntry - nil, // 254: openshell.v1.SandboxTemplate.AnnotationsEntry - nil, // 255: openshell.v1.SandboxTemplate.EnvironmentEntry - nil, // 256: openshell.v1.SandboxWorkloadConfig.EnvironmentEntry - nil, // 257: openshell.v1.PlatformEvent.MetadataEntry - nil, // 258: openshell.v1.CreateSandboxRequest.LabelsEntry - nil, // 259: openshell.v1.CreateSandboxRequest.AnnotationsEntry - nil, // 260: openshell.v1.SandboxResponse.ServiceUrlsEntry - nil, // 261: openshell.v1.ExecSandboxRequest.EnvironmentEntry - nil, // 262: openshell.v1.SandboxLogLine.FieldsEntry - nil, // 263: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry - nil, // 264: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - nil, // 265: openshell.v1.ProviderProfile.AnnotationsEntry - nil, // 266: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - nil, // 267: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry - nil, // 268: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - nil, // 269: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry - nil, // 270: openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry - nil, // 271: openshell.v1.UpdateConfigRequest.AnnotationsEntry - nil, // 272: openshell.v1.UpdateConfigResponse.AnnotationsEntry - nil, // 273: openshell.v1.SandboxPolicyRevision.ProvenanceEntry - nil, // 274: openshell.v1.CreateWorkspaceRequest.LabelsEntry - (*timestamppb.Timestamp)(nil), // 275: google.protobuf.Timestamp - (*datamodelv1.ObjectMeta)(nil), // 276: openshell.datamodel.v1.ObjectMeta - (*sandboxv1.SandboxPolicy)(nil), // 277: openshell.sandbox.v1.SandboxPolicy - (*structpb.Struct)(nil), // 278: google.protobuf.Struct - (*durationpb.Duration)(nil), // 279: google.protobuf.Duration - (*datamodelv1.WorkspaceSelector)(nil), // 280: openshell.datamodel.v1.WorkspaceSelector - (*datamodelv1.Provider)(nil), // 281: openshell.datamodel.v1.Provider - (sandboxv1.PolicySource)(0), // 282: openshell.sandbox.v1.PolicySource - (*sandboxv1.NetworkEndpoint)(nil), // 283: openshell.sandbox.v1.NetworkEndpoint - (*sandboxv1.NetworkBinary)(nil), // 284: openshell.sandbox.v1.NetworkBinary - (*sandboxv1.SettingValue)(nil), // 285: openshell.sandbox.v1.SettingValue - (*sandboxv1.NetworkPolicyRule)(nil), // 286: openshell.sandbox.v1.NetworkPolicyRule - (*sandboxv1.L7DenyRule)(nil), // 287: openshell.sandbox.v1.L7DenyRule - (*sandboxv1.L7Rule)(nil), // 288: openshell.sandbox.v1.L7Rule - (*datamodelv1.Workspace)(nil), // 289: openshell.datamodel.v1.Workspace - (*sandboxv1.GetSandboxConfigRequest)(nil), // 290: openshell.sandbox.v1.GetSandboxConfigRequest - (*sandboxv1.GetGatewayConfigRequest)(nil), // 291: openshell.sandbox.v1.GetGatewayConfigRequest - (*sandboxv1.GetSandboxConfigResponse)(nil), // 292: openshell.sandbox.v1.GetSandboxConfigResponse - (*sandboxv1.GetGatewayConfigResponse)(nil), // 293: openshell.sandbox.v1.GetGatewayConfigResponse + (ProviderEnvironmentValueClassification)(0), // 11: openshell.v1.ProviderEnvironmentValueClassification + (ConfigurationAdmissionState)(0), // 12: openshell.v1.ConfigurationAdmissionState + (PolicyStatus)(0), // 13: openshell.v1.PolicyStatus + (ServiceStatus)(0), // 14: openshell.v1.ServiceStatus + (WorkspaceRole)(0), // 15: openshell.v1.WorkspaceRole + (ProviderCredentialRefreshRecoveryAction)(0), // 16: openshell.v1.ProviderCredentialRefreshRecoveryAction + (SandboxRestartPolicy)(0), // 17: openshell.v1.SandboxRestartPolicy + (DeletionOutcome)(0), // 18: openshell.v1.DeletionOutcome + (EndpointResult)(0), // 19: openshell.v1.EndpointResult + (ServiceAuthorizationMode)(0), // 20: openshell.v1.ServiceAuthorizationMode + (*IssueSandboxTokenRequest)(nil), // 21: openshell.v1.IssueSandboxTokenRequest + (*IssueSandboxTokenResponse)(nil), // 22: openshell.v1.IssueSandboxTokenResponse + (*RefreshSandboxTokenRequest)(nil), // 23: openshell.v1.RefreshSandboxTokenRequest + (*RefreshSandboxTokenResponse)(nil), // 24: openshell.v1.RefreshSandboxTokenResponse + (*HealthRequest)(nil), // 25: openshell.v1.HealthRequest + (*HealthResponse)(nil), // 26: openshell.v1.HealthResponse + (*GetCurrentUserRequest)(nil), // 27: openshell.v1.GetCurrentUserRequest + (*GetCurrentUserResponse)(nil), // 28: openshell.v1.GetCurrentUserResponse + (*GetGatewayInfoRequest)(nil), // 29: openshell.v1.GetGatewayInfoRequest + (*GetGatewayInfoResponse)(nil), // 30: openshell.v1.GetGatewayInfoResponse + (*NegotiatedExtensionInfo)(nil), // 31: openshell.v1.NegotiatedExtensionInfo + (*ComputeDriverInfo)(nil), // 32: openshell.v1.ComputeDriverInfo + (*ComputeDriverCapabilities)(nil), // 33: openshell.v1.ComputeDriverCapabilities + (*ResourceCapabilities)(nil), // 34: openshell.v1.ResourceCapabilities + (*CpuResourceCapabilities)(nil), // 35: openshell.v1.CpuResourceCapabilities + (*MemoryResourceCapabilities)(nil), // 36: openshell.v1.MemoryResourceCapabilities + (*GpuResourceCapabilities)(nil), // 37: openshell.v1.GpuResourceCapabilities + (*Sandbox)(nil), // 38: openshell.v1.Sandbox + (*SandboxSpec)(nil), // 39: openshell.v1.SandboxSpec + (*ResourceRequirements)(nil), // 40: openshell.v1.ResourceRequirements + (*GpuResourceRequirements)(nil), // 41: openshell.v1.GpuResourceRequirements + (*SandboxTemplate)(nil), // 42: openshell.v1.SandboxTemplate + (*SandboxWorkloadTemplate)(nil), // 43: openshell.v1.SandboxWorkloadTemplate + (*SandboxWorkloadTemplateSpec)(nil), // 44: openshell.v1.SandboxWorkloadTemplateSpec + (*SandboxWorkloadConfig)(nil), // 45: openshell.v1.SandboxWorkloadConfig + (*SandboxResources)(nil), // 46: openshell.v1.SandboxResources + (*SandboxServiceLevel)(nil), // 47: openshell.v1.SandboxServiceLevel + (*SandboxStartup)(nil), // 48: openshell.v1.SandboxStartup + (*SandboxWorkloadTemplateProvenance)(nil), // 49: openshell.v1.SandboxWorkloadTemplateProvenance + (*SandboxStatus)(nil), // 50: openshell.v1.SandboxStatus + (*SandboxCondition)(nil), // 51: openshell.v1.SandboxCondition + (*PlatformEvent)(nil), // 52: openshell.v1.PlatformEvent + (*CreateSandboxRequest)(nil), // 53: openshell.v1.CreateSandboxRequest + (*CreateSandboxTemplateRequest)(nil), // 54: openshell.v1.CreateSandboxTemplateRequest + (*GetSandboxTemplateRequest)(nil), // 55: openshell.v1.GetSandboxTemplateRequest + (*ListSandboxTemplatesRequest)(nil), // 56: openshell.v1.ListSandboxTemplatesRequest + (*DeleteSandboxTemplateRequest)(nil), // 57: openshell.v1.DeleteSandboxTemplateRequest + (*SandboxTemplateResponse)(nil), // 58: openshell.v1.SandboxTemplateResponse + (*ListSandboxTemplatesResponse)(nil), // 59: openshell.v1.ListSandboxTemplatesResponse + (*DeleteSandboxTemplateResponse)(nil), // 60: openshell.v1.DeleteSandboxTemplateResponse + (*BeginRootfsTarStagingRequest)(nil), // 61: openshell.v1.BeginRootfsTarStagingRequest + (*BeginRootfsTarStagingResponse)(nil), // 62: openshell.v1.BeginRootfsTarStagingResponse + (*GetSandboxRequest)(nil), // 63: openshell.v1.GetSandboxRequest + (*ListSandboxesRequest)(nil), // 64: openshell.v1.ListSandboxesRequest + (*ListSandboxProvidersRequest)(nil), // 65: openshell.v1.ListSandboxProvidersRequest + (*AttachSandboxProviderRequest)(nil), // 66: openshell.v1.AttachSandboxProviderRequest + (*DetachSandboxProviderRequest)(nil), // 67: openshell.v1.DetachSandboxProviderRequest + (*DeleteSandboxRequest)(nil), // 68: openshell.v1.DeleteSandboxRequest + (*StopSandboxRequest)(nil), // 69: openshell.v1.StopSandboxRequest + (*StartSandboxRequest)(nil), // 70: openshell.v1.StartSandboxRequest + (*SandboxResponse)(nil), // 71: openshell.v1.SandboxResponse + (*ListSandboxesResponse)(nil), // 72: openshell.v1.ListSandboxesResponse + (*ListSandboxProvidersResponse)(nil), // 73: openshell.v1.ListSandboxProvidersResponse + (*AttachSandboxProviderResponse)(nil), // 74: openshell.v1.AttachSandboxProviderResponse + (*DetachSandboxProviderResponse)(nil), // 75: openshell.v1.DetachSandboxProviderResponse + (*ProviderDesiredIdentity)(nil), // 76: openshell.v1.ProviderDesiredIdentity + (*ConfigSnapshotRevision)(nil), // 77: openshell.v1.ConfigSnapshotRevision + (*SandboxConfigRevision)(nil), // 78: openshell.v1.SandboxConfigRevision + (*ConfigUpdateOperation)(nil), // 79: openshell.v1.ConfigUpdateOperation + (*ProviderMutationReceipt)(nil), // 80: openshell.v1.ProviderMutationReceipt + (*ProviderReadinessObservation)(nil), // 81: openshell.v1.ProviderReadinessObservation + (*ProviderReadinessStatus)(nil), // 82: openshell.v1.ProviderReadinessStatus + (*GetSandboxProviderStatusRequest)(nil), // 83: openshell.v1.GetSandboxProviderStatusRequest + (*GetSandboxProviderStatusResponse)(nil), // 84: openshell.v1.GetSandboxProviderStatusResponse + (*ReportProviderReadinessRequest)(nil), // 85: openshell.v1.ReportProviderReadinessRequest + (*ReportProviderReadinessResponse)(nil), // 86: openshell.v1.ReportProviderReadinessResponse + (*DeleteSandboxResponse)(nil), // 87: openshell.v1.DeleteSandboxResponse + (*CreateSshSessionRequest)(nil), // 88: openshell.v1.CreateSshSessionRequest + (*CreateSshSessionResponse)(nil), // 89: openshell.v1.CreateSshSessionResponse + (*ExposeServiceRequest)(nil), // 90: openshell.v1.ExposeServiceRequest + (*GetServiceRequest)(nil), // 91: openshell.v1.GetServiceRequest + (*ListServicesRequest)(nil), // 92: openshell.v1.ListServicesRequest + (*ListServicesResponse)(nil), // 93: openshell.v1.ListServicesResponse + (*DeleteServiceRequest)(nil), // 94: openshell.v1.DeleteServiceRequest + (*DeleteServiceResponse)(nil), // 95: openshell.v1.DeleteServiceResponse + (*ServiceEndpoint)(nil), // 96: openshell.v1.ServiceEndpoint + (*ServiceEndpointResponse)(nil), // 97: openshell.v1.ServiceEndpointResponse + (*RevokeSshSessionRequest)(nil), // 98: openshell.v1.RevokeSshSessionRequest + (*RevokeSshSessionResponse)(nil), // 99: openshell.v1.RevokeSshSessionResponse + (*ExecSandboxRequest)(nil), // 100: openshell.v1.ExecSandboxRequest + (*ExecSandboxStdout)(nil), // 101: openshell.v1.ExecSandboxStdout + (*ExecSandboxStderr)(nil), // 102: openshell.v1.ExecSandboxStderr + (*ExecSandboxExit)(nil), // 103: openshell.v1.ExecSandboxExit + (*ExecSandboxEvent)(nil), // 104: openshell.v1.ExecSandboxEvent + (*TcpForwardInit)(nil), // 105: openshell.v1.TcpForwardInit + (*TcpForwardFrame)(nil), // 106: openshell.v1.TcpForwardFrame + (*ExecSandboxInput)(nil), // 107: openshell.v1.ExecSandboxInput + (*ExecSandboxWindowResize)(nil), // 108: openshell.v1.ExecSandboxWindowResize + (*SshSession)(nil), // 109: openshell.v1.SshSession + (*WatchSandboxRequest)(nil), // 110: openshell.v1.WatchSandboxRequest + (*SandboxStreamEvent)(nil), // 111: openshell.v1.SandboxStreamEvent + (*SandboxLogLine)(nil), // 112: openshell.v1.SandboxLogLine + (*SandboxStreamWarning)(nil), // 113: openshell.v1.SandboxStreamWarning + (*CreateProviderRequest)(nil), // 114: openshell.v1.CreateProviderRequest + (*GetProviderRequest)(nil), // 115: openshell.v1.GetProviderRequest + (*ListProvidersRequest)(nil), // 116: openshell.v1.ListProvidersRequest + (*UpdateProviderRequest)(nil), // 117: openshell.v1.UpdateProviderRequest + (*DeleteProviderRequest)(nil), // 118: openshell.v1.DeleteProviderRequest + (*ProviderResponse)(nil), // 119: openshell.v1.ProviderResponse + (*ListProvidersResponse)(nil), // 120: openshell.v1.ListProvidersResponse + (*ListProviderProfilesRequest)(nil), // 121: openshell.v1.ListProviderProfilesRequest + (*GetProviderProfileRequest)(nil), // 122: openshell.v1.GetProviderProfileRequest + (*ProviderProfileImportItem)(nil), // 123: openshell.v1.ProviderProfileImportItem + (*ProviderProfileDiagnostic)(nil), // 124: openshell.v1.ProviderProfileDiagnostic + (*ProviderCredentialTokenGrantAudienceOverride)(nil), // 125: openshell.v1.ProviderCredentialTokenGrantAudienceOverride + (*ProviderCredentialTokenGrantSubjectToken)(nil), // 126: openshell.v1.ProviderCredentialTokenGrantSubjectToken + (*ProviderCredentialTokenGrant)(nil), // 127: openshell.v1.ProviderCredentialTokenGrant + (*ProviderProfileCredential)(nil), // 128: openshell.v1.ProviderProfileCredential + (*ProviderCredentialRefreshMaterial)(nil), // 129: openshell.v1.ProviderCredentialRefreshMaterial + (*ProviderCredentialRefreshOutput)(nil), // 130: openshell.v1.ProviderCredentialRefreshOutput + (*ProviderCredentialRefresh)(nil), // 131: openshell.v1.ProviderCredentialRefresh + (*ProviderCredentialRefreshStatus)(nil), // 132: openshell.v1.ProviderCredentialRefreshStatus + (*ProviderProfileDiscovery)(nil), // 133: openshell.v1.ProviderProfileDiscovery + (*GetProviderRefreshStatusRequest)(nil), // 134: openshell.v1.GetProviderRefreshStatusRequest + (*GetProviderRefreshStatusResponse)(nil), // 135: openshell.v1.GetProviderRefreshStatusResponse + (*ConfigureProviderRefreshRequest)(nil), // 136: openshell.v1.ConfigureProviderRefreshRequest + (*ConfigureProviderRefreshResponse)(nil), // 137: openshell.v1.ConfigureProviderRefreshResponse + (*RotateProviderCredentialRequest)(nil), // 138: openshell.v1.RotateProviderCredentialRequest + (*RotateProviderCredentialResponse)(nil), // 139: openshell.v1.RotateProviderCredentialResponse + (*DeleteProviderRefreshRequest)(nil), // 140: openshell.v1.DeleteProviderRefreshRequest + (*DeleteProviderRefreshResponse)(nil), // 141: openshell.v1.DeleteProviderRefreshResponse + (*ProviderProfile)(nil), // 142: openshell.v1.ProviderProfile + (*ProviderProfileFile)(nil), // 143: openshell.v1.ProviderProfileFile + (*ProviderProfileResponse)(nil), // 144: openshell.v1.ProviderProfileResponse + (*ListProviderProfilesResponse)(nil), // 145: openshell.v1.ListProviderProfilesResponse + (*ImportProviderProfilesRequest)(nil), // 146: openshell.v1.ImportProviderProfilesRequest + (*ImportProviderProfilesResponse)(nil), // 147: openshell.v1.ImportProviderProfilesResponse + (*UpdateProviderProfilesRequest)(nil), // 148: openshell.v1.UpdateProviderProfilesRequest + (*UpdateProviderProfilesResponse)(nil), // 149: openshell.v1.UpdateProviderProfilesResponse + (*LintProviderProfilesRequest)(nil), // 150: openshell.v1.LintProviderProfilesRequest + (*LintProviderProfilesResponse)(nil), // 151: openshell.v1.LintProviderProfilesResponse + (*DeleteProviderResponse)(nil), // 152: openshell.v1.DeleteProviderResponse + (*DeleteProviderProfileRequest)(nil), // 153: openshell.v1.DeleteProviderProfileRequest + (*DeleteProviderProfileResponse)(nil), // 154: openshell.v1.DeleteProviderProfileResponse + (*GetSandboxProviderEnvironmentRequest)(nil), // 155: openshell.v1.GetSandboxProviderEnvironmentRequest + (*StaticCredentialEndpointBinding)(nil), // 156: openshell.v1.StaticCredentialEndpointBinding + (*StaticCredentialBinding)(nil), // 157: openshell.v1.StaticCredentialBinding + (*GetSandboxProviderEnvironmentResponse)(nil), // 158: openshell.v1.GetSandboxProviderEnvironmentResponse + (*ProviderEnvironmentValue)(nil), // 159: openshell.v1.ProviderEnvironmentValue + (*ProviderEnvironmentSnapshot)(nil), // 160: openshell.v1.ProviderEnvironmentSnapshot + (*ExchangeProviderSubjectTokenRequest)(nil), // 161: openshell.v1.ExchangeProviderSubjectTokenRequest + (*ExchangeProviderSubjectTokenResponse)(nil), // 162: openshell.v1.ExchangeProviderSubjectTokenResponse + (*UpdateConfigRequest)(nil), // 163: openshell.v1.UpdateConfigRequest + (*PolicyMergeOperation)(nil), // 164: openshell.v1.PolicyMergeOperation + (*AddNetworkRule)(nil), // 165: openshell.v1.AddNetworkRule + (*RemoveNetworkEndpoint)(nil), // 166: openshell.v1.RemoveNetworkEndpoint + (*RemoveNetworkRule)(nil), // 167: openshell.v1.RemoveNetworkRule + (*L7RuleTarget)(nil), // 168: openshell.v1.L7RuleTarget + (*AddDenyRules)(nil), // 169: openshell.v1.AddDenyRules + (*AddAllowRules)(nil), // 170: openshell.v1.AddAllowRules + (*RemoveNetworkBinary)(nil), // 171: openshell.v1.RemoveNetworkBinary + (*UpdateConfigResponse)(nil), // 172: openshell.v1.UpdateConfigResponse + (*GetSandboxPolicyStatusRequest)(nil), // 173: openshell.v1.GetSandboxPolicyStatusRequest + (*GetSandboxPolicyStatusResponse)(nil), // 174: openshell.v1.GetSandboxPolicyStatusResponse + (*ListSandboxPoliciesRequest)(nil), // 175: openshell.v1.ListSandboxPoliciesRequest + (*ListSandboxPoliciesResponse)(nil), // 176: openshell.v1.ListSandboxPoliciesResponse + (*ReportPolicyStatusRequest)(nil), // 177: openshell.v1.ReportPolicyStatusRequest + (*ReportPolicyStatusResponse)(nil), // 178: openshell.v1.ReportPolicyStatusResponse + (*SandboxConfigurationAdmission)(nil), // 179: openshell.v1.SandboxConfigurationAdmission + (*ReportSandboxConfigurationRequest)(nil), // 180: openshell.v1.ReportSandboxConfigurationRequest + (*ReportSandboxConfigurationResponse)(nil), // 181: openshell.v1.ReportSandboxConfigurationResponse + (*SandboxPolicyRevision)(nil), // 182: openshell.v1.SandboxPolicyRevision + (*GetSandboxLogsRequest)(nil), // 183: openshell.v1.GetSandboxLogsRequest + (*PushSandboxLogsRequest)(nil), // 184: openshell.v1.PushSandboxLogsRequest + (*PushSandboxLogsResponse)(nil), // 185: openshell.v1.PushSandboxLogsResponse + (*GetSandboxLogsResponse)(nil), // 186: openshell.v1.GetSandboxLogsResponse + (*SupervisorMessage)(nil), // 187: openshell.v1.SupervisorMessage + (*GatewayMessage)(nil), // 188: openshell.v1.GatewayMessage + (*SupervisorHello)(nil), // 189: openshell.v1.SupervisorHello + (*SessionAccepted)(nil), // 190: openshell.v1.SessionAccepted + (*ConfigBootstrap)(nil), // 191: openshell.v1.ConfigBootstrap + (*ConfigUpdate)(nil), // 192: openshell.v1.ConfigUpdate + (*ConfigApplyFailure)(nil), // 193: openshell.v1.ConfigApplyFailure + (*ConfigComponentApplyResult)(nil), // 194: openshell.v1.ConfigComponentApplyResult + (*ConfigUpdateResult)(nil), // 195: openshell.v1.ConfigUpdateResult + (*ConfigBootstrapResult)(nil), // 196: openshell.v1.ConfigBootstrapResult + (*SessionRejected)(nil), // 197: openshell.v1.SessionRejected + (*SupervisorHeartbeat)(nil), // 198: openshell.v1.SupervisorHeartbeat + (*GatewayHeartbeat)(nil), // 199: openshell.v1.GatewayHeartbeat + (*ReportMainProcessExitRequest)(nil), // 200: openshell.v1.ReportMainProcessExitRequest + (*ReportMainProcessExitResponse)(nil), // 201: openshell.v1.ReportMainProcessExitResponse + (*FinalizeMainProcessExitRequest)(nil), // 202: openshell.v1.FinalizeMainProcessExitRequest + (*FinalizeMainProcessExitResponse)(nil), // 203: openshell.v1.FinalizeMainProcessExitResponse + (*RelayOpen)(nil), // 204: openshell.v1.RelayOpen + (*SshRelayTarget)(nil), // 205: openshell.v1.SshRelayTarget + (*TcpRelayTarget)(nil), // 206: openshell.v1.TcpRelayTarget + (*RelayInit)(nil), // 207: openshell.v1.RelayInit + (*RelayFrame)(nil), // 208: openshell.v1.RelayFrame + (*PeerRelayInit)(nil), // 209: openshell.v1.PeerRelayInit + (*PeerRelayFrame)(nil), // 210: openshell.v1.PeerRelayFrame + (*PeerConfigSandboxTarget)(nil), // 211: openshell.v1.PeerConfigSandboxTarget + (*PeerConfigUpdateHintRequest)(nil), // 212: openshell.v1.PeerConfigUpdateHintRequest + (*PeerConfigUpdateHintResponse)(nil), // 213: openshell.v1.PeerConfigUpdateHintResponse + (*RelayOpenResult)(nil), // 214: openshell.v1.RelayOpenResult + (*RelayClose)(nil), // 215: openshell.v1.RelayClose + (*L7RequestSample)(nil), // 216: openshell.v1.L7RequestSample + (*DenialSummary)(nil), // 217: openshell.v1.DenialSummary + (*DenialGroupCount)(nil), // 218: openshell.v1.DenialGroupCount + (*NetworkActivitySummary)(nil), // 219: openshell.v1.NetworkActivitySummary + (*PolicyChunk)(nil), // 220: openshell.v1.PolicyChunk + (*DraftPolicyUpdate)(nil), // 221: openshell.v1.DraftPolicyUpdate + (*SubmitPolicyAnalysisRequest)(nil), // 222: openshell.v1.SubmitPolicyAnalysisRequest + (*SubmitPolicyAnalysisResponse)(nil), // 223: openshell.v1.SubmitPolicyAnalysisResponse + (*GetDraftPolicyRequest)(nil), // 224: openshell.v1.GetDraftPolicyRequest + (*GetDraftPolicyResponse)(nil), // 225: openshell.v1.GetDraftPolicyResponse + (*ApproveDraftChunkRequest)(nil), // 226: openshell.v1.ApproveDraftChunkRequest + (*ApproveDraftChunkResponse)(nil), // 227: openshell.v1.ApproveDraftChunkResponse + (*RejectDraftChunkRequest)(nil), // 228: openshell.v1.RejectDraftChunkRequest + (*RejectDraftChunkResponse)(nil), // 229: openshell.v1.RejectDraftChunkResponse + (*DraftChunkApproval)(nil), // 230: openshell.v1.DraftChunkApproval + (*ApproveAllDraftChunksRequest)(nil), // 231: openshell.v1.ApproveAllDraftChunksRequest + (*ApproveAllDraftChunksResponse)(nil), // 232: openshell.v1.ApproveAllDraftChunksResponse + (*EditDraftChunkRequest)(nil), // 233: openshell.v1.EditDraftChunkRequest + (*EditDraftChunkResponse)(nil), // 234: openshell.v1.EditDraftChunkResponse + (*UndoDraftChunkRequest)(nil), // 235: openshell.v1.UndoDraftChunkRequest + (*UndoDraftChunkResponse)(nil), // 236: openshell.v1.UndoDraftChunkResponse + (*ClearDraftChunksRequest)(nil), // 237: openshell.v1.ClearDraftChunksRequest + (*ClearDraftChunksResponse)(nil), // 238: openshell.v1.ClearDraftChunksResponse + (*GetDraftHistoryRequest)(nil), // 239: openshell.v1.GetDraftHistoryRequest + (*DraftHistoryEntry)(nil), // 240: openshell.v1.DraftHistoryEntry + (*GetDraftHistoryResponse)(nil), // 241: openshell.v1.GetDraftHistoryResponse + (*CreateWorkspaceRequest)(nil), // 242: openshell.v1.CreateWorkspaceRequest + (*CreateWorkspaceResponse)(nil), // 243: openshell.v1.CreateWorkspaceResponse + (*GetWorkspaceRequest)(nil), // 244: openshell.v1.GetWorkspaceRequest + (*GetWorkspaceResponse)(nil), // 245: openshell.v1.GetWorkspaceResponse + (*ListWorkspacesRequest)(nil), // 246: openshell.v1.ListWorkspacesRequest + (*ListWorkspacesResponse)(nil), // 247: openshell.v1.ListWorkspacesResponse + (*DeleteWorkspaceRequest)(nil), // 248: openshell.v1.DeleteWorkspaceRequest + (*DeleteWorkspaceResponse)(nil), // 249: openshell.v1.DeleteWorkspaceResponse + (*WorkspaceMember)(nil), // 250: openshell.v1.WorkspaceMember + (*AddWorkspaceMemberRequest)(nil), // 251: openshell.v1.AddWorkspaceMemberRequest + (*AddWorkspaceMemberResponse)(nil), // 252: openshell.v1.AddWorkspaceMemberResponse + (*RemoveWorkspaceMemberRequest)(nil), // 253: openshell.v1.RemoveWorkspaceMemberRequest + (*RemoveWorkspaceMemberResponse)(nil), // 254: openshell.v1.RemoveWorkspaceMemberResponse + (*ListWorkspaceMembersRequest)(nil), // 255: openshell.v1.ListWorkspaceMembersRequest + (*ListWorkspaceMembersResponse)(nil), // 256: openshell.v1.ListWorkspaceMembersResponse + (*ExtensionServiceCredential)(nil), // 257: openshell.v1.ExtensionServiceCredential + (*EndpointObservation)(nil), // 258: openshell.v1.EndpointObservation + (*ReportEndpointStatusRequest)(nil), // 259: openshell.v1.ReportEndpointStatusRequest + (*ReportEndpointStatusResponse)(nil), // 260: openshell.v1.ReportEndpointStatusResponse + (*EndpointStatus)(nil), // 261: openshell.v1.EndpointStatus + (*SandboxProvisioning)(nil), // 262: openshell.v1.SandboxProvisioning + (*SandboxServiceExposure)(nil), // 263: openshell.v1.SandboxServiceExposure + nil, // 264: openshell.v1.SandboxSpec.EnvironmentEntry + nil, // 265: openshell.v1.SandboxTemplate.LabelsEntry + nil, // 266: openshell.v1.SandboxTemplate.AnnotationsEntry + nil, // 267: openshell.v1.SandboxTemplate.EnvironmentEntry + nil, // 268: openshell.v1.SandboxWorkloadConfig.EnvironmentEntry + nil, // 269: openshell.v1.PlatformEvent.MetadataEntry + nil, // 270: openshell.v1.CreateSandboxRequest.LabelsEntry + nil, // 271: openshell.v1.CreateSandboxRequest.AnnotationsEntry + nil, // 272: openshell.v1.SandboxResponse.ServiceUrlsEntry + nil, // 273: openshell.v1.ExecSandboxRequest.EnvironmentEntry + nil, // 274: openshell.v1.SandboxLogLine.FieldsEntry + nil, // 275: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry + nil, // 276: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + nil, // 277: openshell.v1.ProviderProfile.AnnotationsEntry + nil, // 278: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + nil, // 279: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry + nil, // 280: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + nil, // 281: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + nil, // 282: openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry + nil, // 283: openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry + nil, // 284: openshell.v1.ProviderEnvironmentSnapshot.FilesEntry + nil, // 285: openshell.v1.UpdateConfigRequest.AnnotationsEntry + nil, // 286: openshell.v1.UpdateConfigResponse.AnnotationsEntry + nil, // 287: openshell.v1.SandboxPolicyRevision.ProvenanceEntry + nil, // 288: openshell.v1.CreateWorkspaceRequest.LabelsEntry + (*timestamppb.Timestamp)(nil), // 289: google.protobuf.Timestamp + (*datamodelv1.ObjectMeta)(nil), // 290: openshell.datamodel.v1.ObjectMeta + (*sandboxv1.SandboxPolicy)(nil), // 291: openshell.sandbox.v1.SandboxPolicy + (*structpb.Struct)(nil), // 292: google.protobuf.Struct + (*durationpb.Duration)(nil), // 293: google.protobuf.Duration + (*datamodelv1.WorkspaceSelector)(nil), // 294: openshell.datamodel.v1.WorkspaceSelector + (*datamodelv1.Provider)(nil), // 295: openshell.datamodel.v1.Provider + (sandboxv1.PolicySource)(0), // 296: openshell.sandbox.v1.PolicySource + (*sandboxv1.NetworkEndpoint)(nil), // 297: openshell.sandbox.v1.NetworkEndpoint + (*sandboxv1.NetworkBinary)(nil), // 298: openshell.sandbox.v1.NetworkBinary + (*sandboxv1.SettingValue)(nil), // 299: openshell.sandbox.v1.SettingValue + (*sandboxv1.NetworkPolicyRule)(nil), // 300: openshell.sandbox.v1.NetworkPolicyRule + (*sandboxv1.L7DenyRule)(nil), // 301: openshell.sandbox.v1.L7DenyRule + (*sandboxv1.L7Rule)(nil), // 302: openshell.sandbox.v1.L7Rule + (*sandboxv1.SandboxConfigSnapshot)(nil), // 303: openshell.sandbox.v1.SandboxConfigSnapshot + (*datamodelv1.Workspace)(nil), // 304: openshell.datamodel.v1.Workspace + (*sandboxv1.GetSandboxConfigRequest)(nil), // 305: openshell.sandbox.v1.GetSandboxConfigRequest + (*sandboxv1.GetGatewayConfigRequest)(nil), // 306: openshell.sandbox.v1.GetGatewayConfigRequest + (*sandboxv1.GetSandboxConfigResponse)(nil), // 307: openshell.sandbox.v1.GetSandboxConfigResponse + (*sandboxv1.GetGatewayConfigResponse)(nil), // 308: openshell.sandbox.v1.GetGatewayConfigResponse } var file_openshell_proto_depIdxs = []int32{ - 275, // 0: openshell.v1.IssueSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp - 275, // 1: openshell.v1.RefreshSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp - 245, // 2: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential - 275, // 3: openshell.v1.RefreshSandboxTokenResponse.sandbox_expiration_time:type_name -> google.protobuf.Timestamp - 13, // 4: openshell.v1.HealthResponse.status:type_name -> openshell.v1.ServiceStatus - 13, // 5: openshell.v1.GetGatewayInfoResponse.status:type_name -> openshell.v1.ServiceStatus - 31, // 6: openshell.v1.GetGatewayInfoResponse.compute_drivers:type_name -> openshell.v1.ComputeDriverInfo - 30, // 7: openshell.v1.GetGatewayInfoResponse.extensions:type_name -> openshell.v1.NegotiatedExtensionInfo + 289, // 0: openshell.v1.IssueSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp + 289, // 1: openshell.v1.RefreshSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp + 257, // 2: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential + 289, // 3: openshell.v1.RefreshSandboxTokenResponse.sandbox_expiration_time:type_name -> google.protobuf.Timestamp + 14, // 4: openshell.v1.HealthResponse.status:type_name -> openshell.v1.ServiceStatus + 14, // 5: openshell.v1.GetGatewayInfoResponse.status:type_name -> openshell.v1.ServiceStatus + 32, // 6: openshell.v1.GetGatewayInfoResponse.compute_drivers:type_name -> openshell.v1.ComputeDriverInfo + 31, // 7: openshell.v1.GetGatewayInfoResponse.extensions:type_name -> openshell.v1.NegotiatedExtensionInfo 0, // 8: openshell.v1.NegotiatedExtensionInfo.kind:type_name -> openshell.v1.ExtensionKind - 32, // 9: openshell.v1.ComputeDriverInfo.capabilities:type_name -> openshell.v1.ComputeDriverCapabilities - 33, // 10: openshell.v1.ComputeDriverCapabilities.resource_capabilities:type_name -> openshell.v1.ResourceCapabilities - 34, // 11: openshell.v1.ResourceCapabilities.cpu:type_name -> openshell.v1.CpuResourceCapabilities - 35, // 12: openshell.v1.ResourceCapabilities.memory:type_name -> openshell.v1.MemoryResourceCapabilities - 36, // 13: openshell.v1.ResourceCapabilities.gpu:type_name -> openshell.v1.GpuResourceCapabilities - 276, // 14: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 38, // 15: openshell.v1.Sandbox.spec:type_name -> openshell.v1.SandboxSpec - 49, // 16: openshell.v1.Sandbox.status:type_name -> openshell.v1.SandboxStatus - 48, // 17: openshell.v1.Sandbox.created_from_workload_template:type_name -> openshell.v1.SandboxWorkloadTemplateProvenance - 252, // 18: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry - 41, // 19: openshell.v1.SandboxSpec.template:type_name -> openshell.v1.SandboxTemplate - 277, // 20: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 39, // 21: openshell.v1.SandboxSpec.resource_requirements:type_name -> openshell.v1.ResourceRequirements - 16, // 22: openshell.v1.SandboxSpec.restart_policy:type_name -> openshell.v1.SandboxRestartPolicy - 40, // 23: openshell.v1.ResourceRequirements.gpu:type_name -> openshell.v1.GpuResourceRequirements - 253, // 24: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry - 254, // 25: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry - 255, // 26: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry - 278, // 27: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct - 278, // 28: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct - 276, // 29: openshell.v1.SandboxWorkloadTemplate.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 43, // 30: openshell.v1.SandboxWorkloadTemplate.spec:type_name -> openshell.v1.SandboxWorkloadTemplateSpec - 44, // 31: openshell.v1.SandboxWorkloadTemplateSpec.workload:type_name -> openshell.v1.SandboxWorkloadConfig - 278, // 32: openshell.v1.SandboxWorkloadTemplateSpec.driver_config:type_name -> google.protobuf.Struct - 46, // 33: openshell.v1.SandboxWorkloadTemplateSpec.desired_service_level:type_name -> openshell.v1.SandboxServiceLevel - 256, // 34: openshell.v1.SandboxWorkloadConfig.environment:type_name -> openshell.v1.SandboxWorkloadConfig.EnvironmentEntry - 45, // 35: openshell.v1.SandboxWorkloadConfig.resources:type_name -> openshell.v1.SandboxResources - 40, // 36: openshell.v1.SandboxResources.gpu:type_name -> openshell.v1.GpuResourceRequirements - 47, // 37: openshell.v1.SandboxServiceLevel.startup:type_name -> openshell.v1.SandboxStartup - 279, // 38: openshell.v1.SandboxStartup.ready_within:type_name -> google.protobuf.Duration - 50, // 39: openshell.v1.SandboxStatus.conditions:type_name -> openshell.v1.SandboxCondition + 33, // 9: openshell.v1.ComputeDriverInfo.capabilities:type_name -> openshell.v1.ComputeDriverCapabilities + 34, // 10: openshell.v1.ComputeDriverCapabilities.resource_capabilities:type_name -> openshell.v1.ResourceCapabilities + 35, // 11: openshell.v1.ResourceCapabilities.cpu:type_name -> openshell.v1.CpuResourceCapabilities + 36, // 12: openshell.v1.ResourceCapabilities.memory:type_name -> openshell.v1.MemoryResourceCapabilities + 37, // 13: openshell.v1.ResourceCapabilities.gpu:type_name -> openshell.v1.GpuResourceCapabilities + 290, // 14: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 39, // 15: openshell.v1.Sandbox.spec:type_name -> openshell.v1.SandboxSpec + 50, // 16: openshell.v1.Sandbox.status:type_name -> openshell.v1.SandboxStatus + 49, // 17: openshell.v1.Sandbox.created_from_workload_template:type_name -> openshell.v1.SandboxWorkloadTemplateProvenance + 264, // 18: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry + 42, // 19: openshell.v1.SandboxSpec.template:type_name -> openshell.v1.SandboxTemplate + 291, // 20: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 40, // 21: openshell.v1.SandboxSpec.resource_requirements:type_name -> openshell.v1.ResourceRequirements + 17, // 22: openshell.v1.SandboxSpec.restart_policy:type_name -> openshell.v1.SandboxRestartPolicy + 41, // 23: openshell.v1.ResourceRequirements.gpu:type_name -> openshell.v1.GpuResourceRequirements + 265, // 24: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry + 266, // 25: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry + 267, // 26: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry + 292, // 27: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct + 292, // 28: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct + 290, // 29: openshell.v1.SandboxWorkloadTemplate.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 44, // 30: openshell.v1.SandboxWorkloadTemplate.spec:type_name -> openshell.v1.SandboxWorkloadTemplateSpec + 45, // 31: openshell.v1.SandboxWorkloadTemplateSpec.workload:type_name -> openshell.v1.SandboxWorkloadConfig + 292, // 32: openshell.v1.SandboxWorkloadTemplateSpec.driver_config:type_name -> google.protobuf.Struct + 47, // 33: openshell.v1.SandboxWorkloadTemplateSpec.desired_service_level:type_name -> openshell.v1.SandboxServiceLevel + 268, // 34: openshell.v1.SandboxWorkloadConfig.environment:type_name -> openshell.v1.SandboxWorkloadConfig.EnvironmentEntry + 46, // 35: openshell.v1.SandboxWorkloadConfig.resources:type_name -> openshell.v1.SandboxResources + 41, // 36: openshell.v1.SandboxResources.gpu:type_name -> openshell.v1.GpuResourceRequirements + 48, // 37: openshell.v1.SandboxServiceLevel.startup:type_name -> openshell.v1.SandboxStartup + 293, // 38: openshell.v1.SandboxStartup.ready_within:type_name -> google.protobuf.Duration + 51, // 39: openshell.v1.SandboxStatus.conditions:type_name -> openshell.v1.SandboxCondition 1, // 40: openshell.v1.SandboxStatus.phase:type_name -> openshell.v1.SandboxPhase - 249, // 41: openshell.v1.SandboxStatus.endpoint_statuses:type_name -> openshell.v1.EndpointStatus - 176, // 42: openshell.v1.SandboxStatus.configuration_admission:type_name -> openshell.v1.SandboxConfigurationAdmission - 250, // 43: openshell.v1.SandboxStatus.provisioning:type_name -> openshell.v1.SandboxProvisioning - 275, // 44: openshell.v1.SandboxStatus.next_restart_time:type_name -> google.protobuf.Timestamp - 275, // 45: openshell.v1.SandboxStatus.main_process_started_time:type_name -> google.protobuf.Timestamp - 275, // 46: openshell.v1.SandboxCondition.transition_time:type_name -> google.protobuf.Timestamp - 275, // 47: openshell.v1.PlatformEvent.event_time:type_name -> google.protobuf.Timestamp - 257, // 48: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry - 280, // 49: openshell.v1.CreateSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 38, // 50: openshell.v1.CreateSandboxRequest.spec:type_name -> openshell.v1.SandboxSpec - 258, // 51: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry - 259, // 52: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry - 251, // 53: openshell.v1.CreateSandboxRequest.service_exposures:type_name -> openshell.v1.SandboxServiceExposure - 280, // 54: openshell.v1.CreateSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 42, // 55: openshell.v1.CreateSandboxTemplateRequest.template:type_name -> openshell.v1.SandboxWorkloadTemplate - 280, // 56: openshell.v1.GetSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 57: openshell.v1.ListSandboxTemplatesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 58: openshell.v1.DeleteSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 42, // 59: openshell.v1.SandboxTemplateResponse.template:type_name -> openshell.v1.SandboxWorkloadTemplate - 42, // 60: openshell.v1.ListSandboxTemplatesResponse.templates:type_name -> openshell.v1.SandboxWorkloadTemplate - 17, // 61: openshell.v1.DeleteSandboxTemplateResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 280, // 62: openshell.v1.BeginRootfsTarStagingRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 275, // 63: openshell.v1.BeginRootfsTarStagingResponse.expiration_time:type_name -> google.protobuf.Timestamp - 280, // 64: openshell.v1.GetSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 65: openshell.v1.ListSandboxesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 66: openshell.v1.ListSandboxProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 67: openshell.v1.AttachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 68: openshell.v1.DetachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 69: openshell.v1.DeleteSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 70: openshell.v1.StopSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 71: openshell.v1.StartSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 37, // 72: openshell.v1.SandboxResponse.sandbox:type_name -> openshell.v1.Sandbox - 260, // 73: openshell.v1.SandboxResponse.service_urls:type_name -> openshell.v1.SandboxResponse.ServiceUrlsEntry - 37, // 74: openshell.v1.ListSandboxesResponse.sandboxes:type_name -> openshell.v1.Sandbox - 281, // 75: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider - 37, // 76: openshell.v1.AttachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox - 79, // 77: openshell.v1.AttachSandboxProviderResponse.receipt:type_name -> openshell.v1.ProviderMutationReceipt - 37, // 78: openshell.v1.DetachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox - 79, // 79: openshell.v1.DetachSandboxProviderResponse.receipt:type_name -> openshell.v1.ProviderMutationReceipt - 77, // 80: openshell.v1.ConfigSnapshotRevision.sandbox_config:type_name -> openshell.v1.SandboxConfigRevision - 75, // 81: openshell.v1.ConfigSnapshotRevision.provider_target:type_name -> openshell.v1.ProviderDesiredIdentity - 282, // 82: openshell.v1.SandboxConfigRevision.policy_source:type_name -> openshell.sandbox.v1.PolicySource + 261, // 41: openshell.v1.SandboxStatus.endpoint_statuses:type_name -> openshell.v1.EndpointStatus + 179, // 42: openshell.v1.SandboxStatus.configuration_admission:type_name -> openshell.v1.SandboxConfigurationAdmission + 262, // 43: openshell.v1.SandboxStatus.provisioning:type_name -> openshell.v1.SandboxProvisioning + 289, // 44: openshell.v1.SandboxStatus.next_restart_time:type_name -> google.protobuf.Timestamp + 289, // 45: openshell.v1.SandboxStatus.main_process_started_time:type_name -> google.protobuf.Timestamp + 289, // 46: openshell.v1.SandboxCondition.transition_time:type_name -> google.protobuf.Timestamp + 289, // 47: openshell.v1.PlatformEvent.event_time:type_name -> google.protobuf.Timestamp + 269, // 48: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry + 294, // 49: openshell.v1.CreateSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 39, // 50: openshell.v1.CreateSandboxRequest.spec:type_name -> openshell.v1.SandboxSpec + 270, // 51: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry + 271, // 52: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry + 263, // 53: openshell.v1.CreateSandboxRequest.service_exposures:type_name -> openshell.v1.SandboxServiceExposure + 294, // 54: openshell.v1.CreateSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 43, // 55: openshell.v1.CreateSandboxTemplateRequest.template:type_name -> openshell.v1.SandboxWorkloadTemplate + 294, // 56: openshell.v1.GetSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 57: openshell.v1.ListSandboxTemplatesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 58: openshell.v1.DeleteSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 43, // 59: openshell.v1.SandboxTemplateResponse.template:type_name -> openshell.v1.SandboxWorkloadTemplate + 43, // 60: openshell.v1.ListSandboxTemplatesResponse.templates:type_name -> openshell.v1.SandboxWorkloadTemplate + 18, // 61: openshell.v1.DeleteSandboxTemplateResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 294, // 62: openshell.v1.BeginRootfsTarStagingRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 289, // 63: openshell.v1.BeginRootfsTarStagingResponse.expiration_time:type_name -> google.protobuf.Timestamp + 294, // 64: openshell.v1.GetSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 65: openshell.v1.ListSandboxesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 66: openshell.v1.ListSandboxProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 67: openshell.v1.AttachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 68: openshell.v1.DetachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 69: openshell.v1.DeleteSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 70: openshell.v1.StopSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 71: openshell.v1.StartSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 38, // 72: openshell.v1.SandboxResponse.sandbox:type_name -> openshell.v1.Sandbox + 272, // 73: openshell.v1.SandboxResponse.service_urls:type_name -> openshell.v1.SandboxResponse.ServiceUrlsEntry + 38, // 74: openshell.v1.ListSandboxesResponse.sandboxes:type_name -> openshell.v1.Sandbox + 295, // 75: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 38, // 76: openshell.v1.AttachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox + 80, // 77: openshell.v1.AttachSandboxProviderResponse.receipt:type_name -> openshell.v1.ProviderMutationReceipt + 38, // 78: openshell.v1.DetachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox + 80, // 79: openshell.v1.DetachSandboxProviderResponse.receipt:type_name -> openshell.v1.ProviderMutationReceipt + 78, // 80: openshell.v1.ConfigSnapshotRevision.sandbox_config:type_name -> openshell.v1.SandboxConfigRevision + 76, // 81: openshell.v1.ConfigSnapshotRevision.provider_target:type_name -> openshell.v1.ProviderDesiredIdentity + 296, // 82: openshell.v1.SandboxConfigRevision.policy_source:type_name -> openshell.sandbox.v1.PolicySource 5, // 83: openshell.v1.ConfigUpdateOperation.component:type_name -> openshell.v1.ConfigComponent - 76, // 84: openshell.v1.ConfigUpdateOperation.target_revision:type_name -> openshell.v1.ConfigSnapshotRevision + 77, // 84: openshell.v1.ConfigUpdateOperation.target_revision:type_name -> openshell.v1.ConfigSnapshotRevision 7, // 85: openshell.v1.ConfigUpdateOperation.state:type_name -> openshell.v1.ConfigUpdateOperationState 6, // 86: openshell.v1.ConfigUpdateOperation.outcome:type_name -> openshell.v1.ConfigApplyOutcome - 275, // 87: openshell.v1.ConfigUpdateOperation.created_time:type_name -> google.protobuf.Timestamp - 275, // 88: openshell.v1.ConfigUpdateOperation.updated_time:type_name -> google.protobuf.Timestamp - 275, // 89: openshell.v1.ConfigUpdateOperation.completed_time:type_name -> google.protobuf.Timestamp + 289, // 87: openshell.v1.ConfigUpdateOperation.created_time:type_name -> google.protobuf.Timestamp + 289, // 88: openshell.v1.ConfigUpdateOperation.updated_time:type_name -> google.protobuf.Timestamp + 289, // 89: openshell.v1.ConfigUpdateOperation.completed_time:type_name -> google.protobuf.Timestamp 2, // 90: openshell.v1.ProviderMutationReceipt.kind:type_name -> openshell.v1.ProviderMutationKind - 75, // 91: openshell.v1.ProviderMutationReceipt.desired:type_name -> openshell.v1.ProviderDesiredIdentity - 275, // 92: openshell.v1.ProviderMutationReceipt.persisted_time:type_name -> google.protobuf.Timestamp + 76, // 91: openshell.v1.ProviderMutationReceipt.desired:type_name -> openshell.v1.ProviderDesiredIdentity + 289, // 92: openshell.v1.ProviderMutationReceipt.persisted_time:type_name -> google.protobuf.Timestamp 4, // 93: openshell.v1.ProviderReadinessObservation.reason:type_name -> openshell.v1.ProviderReadinessReason - 79, // 94: openshell.v1.ProviderReadinessStatus.receipt:type_name -> openshell.v1.ProviderMutationReceipt + 80, // 94: openshell.v1.ProviderReadinessStatus.receipt:type_name -> openshell.v1.ProviderMutationReceipt 3, // 95: openshell.v1.ProviderReadinessStatus.state:type_name -> openshell.v1.ProviderReadinessState 4, // 96: openshell.v1.ProviderReadinessStatus.reason:type_name -> openshell.v1.ProviderReadinessReason - 80, // 97: openshell.v1.ProviderReadinessStatus.observed:type_name -> openshell.v1.ProviderReadinessObservation - 275, // 98: openshell.v1.ProviderReadinessStatus.observed_time:type_name -> google.protobuf.Timestamp - 275, // 99: openshell.v1.ProviderReadinessStatus.evaluated_time:type_name -> google.protobuf.Timestamp - 78, // 100: openshell.v1.ProviderReadinessStatus.operation:type_name -> openshell.v1.ConfigUpdateOperation - 280, // 101: openshell.v1.GetSandboxProviderStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 81, // 102: openshell.v1.GetSandboxProviderStatusResponse.status:type_name -> openshell.v1.ProviderReadinessStatus - 80, // 103: openshell.v1.ReportProviderReadinessRequest.observation:type_name -> openshell.v1.ProviderReadinessObservation - 279, // 104: openshell.v1.ReportProviderReadinessResponse.report_interval:type_name -> google.protobuf.Duration - 279, // 105: openshell.v1.ReportProviderReadinessResponse.observation_ttl:type_name -> google.protobuf.Duration - 17, // 106: openshell.v1.DeleteSandboxResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 280, // 107: openshell.v1.CreateSshSessionRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 275, // 108: openshell.v1.CreateSshSessionResponse.expiration_time:type_name -> google.protobuf.Timestamp - 280, // 109: openshell.v1.ExposeServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 19, // 110: openshell.v1.ExposeServiceRequest.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode - 280, // 111: openshell.v1.GetServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 112: openshell.v1.ListServicesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 96, // 113: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse - 280, // 114: openshell.v1.DeleteServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 17, // 115: openshell.v1.DeleteServiceResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 276, // 116: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 19, // 117: openshell.v1.ServiceEndpoint.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode - 95, // 118: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint - 17, // 119: openshell.v1.RevokeSshSessionResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 280, // 120: openshell.v1.ExecSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 261, // 121: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry - 279, // 122: openshell.v1.ExecSandboxRequest.execution_timeout:type_name -> google.protobuf.Duration - 100, // 123: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout - 101, // 124: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr - 102, // 125: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit - 196, // 126: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget - 197, // 127: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget - 104, // 128: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit - 99, // 129: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest - 107, // 130: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize - 276, // 131: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 275, // 132: openshell.v1.SshSession.expiration_time:type_name -> google.protobuf.Timestamp - 280, // 133: openshell.v1.WatchSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 275, // 134: openshell.v1.WatchSandboxRequest.since_time:type_name -> google.protobuf.Timestamp - 37, // 135: openshell.v1.SandboxStreamEvent.sandbox:type_name -> openshell.v1.Sandbox - 111, // 136: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine - 51, // 137: openshell.v1.SandboxStreamEvent.event:type_name -> openshell.v1.PlatformEvent - 112, // 138: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning - 209, // 139: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate - 275, // 140: openshell.v1.SandboxLogLine.event_time:type_name -> google.protobuf.Timestamp - 262, // 141: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry - 280, // 142: openshell.v1.CreateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 281, // 143: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 280, // 144: openshell.v1.GetProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 145: openshell.v1.ListProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 146: openshell.v1.UpdateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 281, // 147: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 263, // 148: openshell.v1.UpdateProviderRequest.credential_expiration_times:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry - 280, // 149: openshell.v1.DeleteProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 281, // 150: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider - 79, // 151: openshell.v1.ProviderResponse.target_receipts:type_name -> openshell.v1.ProviderMutationReceipt - 281, // 152: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider - 280, // 153: openshell.v1.ListProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 154: openshell.v1.GetProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 141, // 155: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile - 279, // 156: openshell.v1.ProviderCredentialTokenGrant.cache_ttl:type_name -> google.protobuf.Duration - 124, // 157: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride + 81, // 97: openshell.v1.ProviderReadinessStatus.observed:type_name -> openshell.v1.ProviderReadinessObservation + 289, // 98: openshell.v1.ProviderReadinessStatus.observed_time:type_name -> google.protobuf.Timestamp + 289, // 99: openshell.v1.ProviderReadinessStatus.evaluated_time:type_name -> google.protobuf.Timestamp + 79, // 100: openshell.v1.ProviderReadinessStatus.operation:type_name -> openshell.v1.ConfigUpdateOperation + 294, // 101: openshell.v1.GetSandboxProviderStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 82, // 102: openshell.v1.GetSandboxProviderStatusResponse.status:type_name -> openshell.v1.ProviderReadinessStatus + 81, // 103: openshell.v1.ReportProviderReadinessRequest.observation:type_name -> openshell.v1.ProviderReadinessObservation + 293, // 104: openshell.v1.ReportProviderReadinessResponse.report_interval:type_name -> google.protobuf.Duration + 293, // 105: openshell.v1.ReportProviderReadinessResponse.observation_ttl:type_name -> google.protobuf.Duration + 18, // 106: openshell.v1.DeleteSandboxResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 294, // 107: openshell.v1.CreateSshSessionRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 289, // 108: openshell.v1.CreateSshSessionResponse.expiration_time:type_name -> google.protobuf.Timestamp + 294, // 109: openshell.v1.ExposeServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 20, // 110: openshell.v1.ExposeServiceRequest.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode + 294, // 111: openshell.v1.GetServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 112: openshell.v1.ListServicesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 97, // 113: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse + 294, // 114: openshell.v1.DeleteServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 18, // 115: openshell.v1.DeleteServiceResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 290, // 116: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 20, // 117: openshell.v1.ServiceEndpoint.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode + 96, // 118: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint + 18, // 119: openshell.v1.RevokeSshSessionResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 294, // 120: openshell.v1.ExecSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 273, // 121: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry + 293, // 122: openshell.v1.ExecSandboxRequest.execution_timeout:type_name -> google.protobuf.Duration + 101, // 123: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout + 102, // 124: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr + 103, // 125: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit + 205, // 126: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget + 206, // 127: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget + 105, // 128: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit + 100, // 129: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest + 108, // 130: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize + 290, // 131: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 289, // 132: openshell.v1.SshSession.expiration_time:type_name -> google.protobuf.Timestamp + 294, // 133: openshell.v1.WatchSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 289, // 134: openshell.v1.WatchSandboxRequest.since_time:type_name -> google.protobuf.Timestamp + 38, // 135: openshell.v1.SandboxStreamEvent.sandbox:type_name -> openshell.v1.Sandbox + 112, // 136: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine + 52, // 137: openshell.v1.SandboxStreamEvent.event:type_name -> openshell.v1.PlatformEvent + 113, // 138: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning + 221, // 139: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate + 289, // 140: openshell.v1.SandboxLogLine.event_time:type_name -> google.protobuf.Timestamp + 274, // 141: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry + 294, // 142: openshell.v1.CreateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 295, // 143: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 294, // 144: openshell.v1.GetProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 145: openshell.v1.ListProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 146: openshell.v1.UpdateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 295, // 147: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 275, // 148: openshell.v1.UpdateProviderRequest.credential_expiration_times:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry + 294, // 149: openshell.v1.DeleteProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 295, // 150: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider + 80, // 151: openshell.v1.ProviderResponse.target_receipts:type_name -> openshell.v1.ProviderMutationReceipt + 295, // 152: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 294, // 153: openshell.v1.ListProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 154: openshell.v1.GetProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 142, // 155: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile + 293, // 156: openshell.v1.ProviderCredentialTokenGrant.cache_ttl:type_name -> google.protobuf.Duration + 125, // 157: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride 8, // 158: openshell.v1.ProviderCredentialTokenGrant.grant_type:type_name -> openshell.v1.ProviderCredentialTokenGrantType - 125, // 159: openshell.v1.ProviderCredentialTokenGrant.subject_token:type_name -> openshell.v1.ProviderCredentialTokenGrantSubjectToken - 130, // 160: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh - 126, // 161: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant + 126, // 159: openshell.v1.ProviderCredentialTokenGrant.subject_token:type_name -> openshell.v1.ProviderCredentialTokenGrantSubjectToken + 131, // 160: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh + 127, // 161: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant 9, // 162: openshell.v1.ProviderCredentialRefresh.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 279, // 163: openshell.v1.ProviderCredentialRefresh.refresh_before:type_name -> google.protobuf.Duration - 279, // 164: openshell.v1.ProviderCredentialRefresh.max_lifetime:type_name -> google.protobuf.Duration - 128, // 165: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial - 129, // 166: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput + 293, // 163: openshell.v1.ProviderCredentialRefresh.refresh_before:type_name -> google.protobuf.Duration + 293, // 164: openshell.v1.ProviderCredentialRefresh.max_lifetime:type_name -> google.protobuf.Duration + 129, // 165: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial + 130, // 166: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput 9, // 167: openshell.v1.ProviderCredentialRefreshStatus.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 275, // 168: openshell.v1.ProviderCredentialRefreshStatus.expiration_time:type_name -> google.protobuf.Timestamp - 275, // 169: openshell.v1.ProviderCredentialRefreshStatus.next_refresh_time:type_name -> google.protobuf.Timestamp - 275, // 170: openshell.v1.ProviderCredentialRefreshStatus.last_refresh_time:type_name -> google.protobuf.Timestamp - 15, // 171: openshell.v1.ProviderCredentialRefreshStatus.recovery_action:type_name -> openshell.v1.ProviderCredentialRefreshRecoveryAction - 275, // 172: openshell.v1.ProviderCredentialRefreshStatus.last_error_time:type_name -> google.protobuf.Timestamp - 280, // 173: openshell.v1.GetProviderRefreshStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 131, // 174: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 280, // 175: openshell.v1.ConfigureProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 289, // 168: openshell.v1.ProviderCredentialRefreshStatus.expiration_time:type_name -> google.protobuf.Timestamp + 289, // 169: openshell.v1.ProviderCredentialRefreshStatus.next_refresh_time:type_name -> google.protobuf.Timestamp + 289, // 170: openshell.v1.ProviderCredentialRefreshStatus.last_refresh_time:type_name -> google.protobuf.Timestamp + 16, // 171: openshell.v1.ProviderCredentialRefreshStatus.recovery_action:type_name -> openshell.v1.ProviderCredentialRefreshRecoveryAction + 289, // 172: openshell.v1.ProviderCredentialRefreshStatus.last_error_time:type_name -> google.protobuf.Timestamp + 294, // 173: openshell.v1.GetProviderRefreshStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 132, // 174: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 294, // 175: openshell.v1.ConfigureProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 9, // 176: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 264, // 177: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - 275, // 178: openshell.v1.ConfigureProviderRefreshRequest.expiration_time:type_name -> google.protobuf.Timestamp - 131, // 179: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 280, // 180: openshell.v1.RotateProviderCredentialRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 131, // 181: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 280, // 182: openshell.v1.DeleteProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 17, // 183: openshell.v1.DeleteProviderRefreshResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 276, // 177: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + 289, // 178: openshell.v1.ConfigureProviderRefreshRequest.expiration_time:type_name -> google.protobuf.Timestamp + 132, // 179: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 294, // 180: openshell.v1.RotateProviderCredentialRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 132, // 181: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 294, // 182: openshell.v1.DeleteProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 18, // 183: openshell.v1.DeleteProviderRefreshResponse.outcome:type_name -> openshell.v1.DeletionOutcome 10, // 184: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory - 127, // 185: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential - 283, // 186: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint - 284, // 187: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 132, // 188: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery - 265, // 189: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry - 142, // 190: openshell.v1.ProviderProfile.files:type_name -> openshell.v1.ProviderProfileFile - 141, // 191: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile - 141, // 192: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 280, // 193: openshell.v1.ImportProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 122, // 194: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 123, // 195: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 141, // 196: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 280, // 197: openshell.v1.UpdateProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 122, // 198: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem - 123, // 199: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 141, // 200: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile - 280, // 201: openshell.v1.LintProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 122, // 202: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 123, // 203: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 17, // 204: openshell.v1.DeleteProviderResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 280, // 205: openshell.v1.DeleteProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 17, // 206: openshell.v1.DeleteProviderProfileResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 155, // 207: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding - 266, // 208: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - 267, // 209: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expiration_times:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry - 268, // 210: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - 269, // 211: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + 128, // 185: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential + 297, // 186: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint + 298, // 187: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 133, // 188: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery + 277, // 189: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry + 143, // 190: openshell.v1.ProviderProfile.files:type_name -> openshell.v1.ProviderProfileFile + 142, // 191: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile + 142, // 192: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 294, // 193: openshell.v1.ImportProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 123, // 194: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 124, // 195: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 142, // 196: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 294, // 197: openshell.v1.UpdateProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 123, // 198: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem + 124, // 199: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 142, // 200: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile + 294, // 201: openshell.v1.LintProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 123, // 202: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 124, // 203: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 18, // 204: openshell.v1.DeleteProviderResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 294, // 205: openshell.v1.DeleteProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 18, // 206: openshell.v1.DeleteProviderProfileResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 156, // 207: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding + 278, // 208: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + 279, // 209: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expiration_times:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry + 280, // 210: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + 281, // 211: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry 4, // 212: openshell.v1.GetSandboxProviderEnvironmentResponse.readiness_reason:type_name -> openshell.v1.ProviderReadinessReason - 270, // 213: openshell.v1.GetSandboxProviderEnvironmentResponse.files:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry - 279, // 214: openshell.v1.ExchangeProviderSubjectTokenResponse.expires_after:type_name -> google.protobuf.Duration - 280, // 215: openshell.v1.UpdateConfigRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 277, // 216: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 285, // 217: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue - 161, // 218: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation - 271, // 219: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry - 162, // 220: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule - 163, // 221: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint - 164, // 222: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule - 166, // 223: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules - 167, // 224: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules - 168, // 225: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary - 286, // 226: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 284, // 227: openshell.v1.L7RuleTarget.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 287, // 228: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule - 165, // 229: openshell.v1.AddDenyRules.target:type_name -> openshell.v1.L7RuleTarget - 288, // 230: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule - 165, // 231: openshell.v1.AddAllowRules.target:type_name -> openshell.v1.L7RuleTarget - 272, // 232: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry - 280, // 233: openshell.v1.GetSandboxPolicyStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 179, // 234: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision - 280, // 235: openshell.v1.ListSandboxPoliciesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 179, // 236: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision - 12, // 237: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus - 11, // 238: openshell.v1.SandboxConfigurationAdmission.state:type_name -> openshell.v1.ConfigurationAdmissionState - 176, // 239: openshell.v1.ReportSandboxConfigurationRequest.admission:type_name -> openshell.v1.SandboxConfigurationAdmission - 12, // 240: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus - 275, // 241: openshell.v1.SandboxPolicyRevision.created_time:type_name -> google.protobuf.Timestamp - 275, // 242: openshell.v1.SandboxPolicyRevision.loaded_time:type_name -> google.protobuf.Timestamp - 277, // 243: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 273, // 244: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry - 280, // 245: openshell.v1.GetSandboxLogsRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 275, // 246: openshell.v1.GetSandboxLogsRequest.since_time:type_name -> google.protobuf.Timestamp - 111, // 247: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine - 111, // 248: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine - 186, // 249: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello - 189, // 250: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat - 202, // 251: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult - 203, // 252: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose - 187, // 253: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted - 188, // 254: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected - 190, // 255: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat - 195, // 256: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen - 203, // 257: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose - 279, // 258: openshell.v1.SessionAccepted.heartbeat_interval:type_name -> google.protobuf.Duration - 196, // 259: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget - 197, // 260: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget - 198, // 261: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit - 195, // 262: openshell.v1.PeerRelayInit.relay_open:type_name -> openshell.v1.RelayOpen - 200, // 263: openshell.v1.PeerRelayFrame.init:type_name -> openshell.v1.PeerRelayInit - 275, // 264: openshell.v1.DenialSummary.first_seen_time:type_name -> google.protobuf.Timestamp - 275, // 265: openshell.v1.DenialSummary.last_seen_time:type_name -> google.protobuf.Timestamp - 204, // 266: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample - 206, // 267: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount - 286, // 268: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 275, // 269: openshell.v1.PolicyChunk.created_time:type_name -> google.protobuf.Timestamp - 275, // 270: openshell.v1.PolicyChunk.decided_time:type_name -> google.protobuf.Timestamp - 275, // 271: openshell.v1.PolicyChunk.first_seen_time:type_name -> google.protobuf.Timestamp - 275, // 272: openshell.v1.PolicyChunk.last_seen_time:type_name -> google.protobuf.Timestamp - 277, // 273: openshell.v1.PolicyChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 277, // 274: openshell.v1.PolicyChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 280, // 275: openshell.v1.SubmitPolicyAnalysisRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 205, // 276: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary - 208, // 277: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk - 207, // 278: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary - 280, // 279: openshell.v1.GetDraftPolicyRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 208, // 280: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk - 275, // 281: openshell.v1.GetDraftPolicyResponse.last_analyzed_time:type_name -> google.protobuf.Timestamp - 280, // 282: openshell.v1.ApproveDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 283: openshell.v1.RejectDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 284: openshell.v1.ApproveAllDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 218, // 285: openshell.v1.ApproveAllDraftChunksRequest.approvals:type_name -> openshell.v1.DraftChunkApproval - 280, // 286: openshell.v1.EditDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 286, // 287: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 280, // 288: openshell.v1.UndoDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 289: openshell.v1.ClearDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 280, // 290: openshell.v1.GetDraftHistoryRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 275, // 291: openshell.v1.DraftHistoryEntry.event_time:type_name -> google.protobuf.Timestamp - 228, // 292: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry - 274, // 293: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry - 289, // 294: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 289, // 295: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 289, // 296: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace - 17, // 297: openshell.v1.DeleteWorkspaceResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 276, // 298: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 14, // 299: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole - 280, // 300: openshell.v1.AddWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 14, // 301: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole - 238, // 302: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember - 280, // 303: openshell.v1.RemoveWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 17, // 304: openshell.v1.RemoveWorkspaceMemberResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 280, // 305: openshell.v1.ListWorkspaceMembersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 238, // 306: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember - 275, // 307: openshell.v1.ExtensionServiceCredential.expiration_time:type_name -> google.protobuf.Timestamp - 18, // 308: openshell.v1.EndpointObservation.result:type_name -> openshell.v1.EndpointResult - 246, // 309: openshell.v1.ReportEndpointStatusRequest.observations:type_name -> openshell.v1.EndpointObservation - 18, // 310: openshell.v1.EndpointStatus.last_result:type_name -> openshell.v1.EndpointResult - 275, // 311: openshell.v1.EndpointStatus.last_reported_time:type_name -> google.protobuf.Timestamp - 275, // 312: openshell.v1.SandboxProvisioning.configuration_change_time:type_name -> google.protobuf.Timestamp - 275, // 313: openshell.v1.SandboxProvisioning.first_rejection_time:type_name -> google.protobuf.Timestamp - 275, // 314: openshell.v1.SandboxProvisioning.deadline:type_name -> google.protobuf.Timestamp - 275, // 315: openshell.v1.SandboxProvisioning.timeout_time:type_name -> google.protobuf.Timestamp - 275, // 316: openshell.v1.SandboxProvisioning.cleanup_completed_time:type_name -> google.protobuf.Timestamp - 275, // 317: openshell.v1.SandboxProvisioning.cleanup_retry_time:type_name -> google.protobuf.Timestamp - 275, // 318: openshell.v1.SandboxProvisioning.attachment_change_time:type_name -> google.protobuf.Timestamp - 19, // 319: openshell.v1.SandboxServiceExposure.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode - 275, // 320: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp - 275, // 321: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp - 127, // 322: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential - 156, // 323: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding - 24, // 324: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest - 26, // 325: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest - 28, // 326: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest - 52, // 327: openshell.v1.OpenShell.CreateSandbox:input_type -> openshell.v1.CreateSandboxRequest - 60, // 328: openshell.v1.OpenShell.BeginRootfsTarStaging:input_type -> openshell.v1.BeginRootfsTarStagingRequest - 62, // 329: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest - 63, // 330: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest - 53, // 331: openshell.v1.OpenShell.CreateSandboxTemplate:input_type -> openshell.v1.CreateSandboxTemplateRequest - 54, // 332: openshell.v1.OpenShell.GetSandboxTemplate:input_type -> openshell.v1.GetSandboxTemplateRequest - 55, // 333: openshell.v1.OpenShell.ListSandboxTemplates:input_type -> openshell.v1.ListSandboxTemplatesRequest - 56, // 334: openshell.v1.OpenShell.DeleteSandboxTemplate:input_type -> openshell.v1.DeleteSandboxTemplateRequest - 64, // 335: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest - 65, // 336: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest - 66, // 337: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest - 82, // 338: openshell.v1.OpenShell.GetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest - 67, // 339: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest - 68, // 340: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest - 69, // 341: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest - 87, // 342: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest - 89, // 343: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest - 90, // 344: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest - 91, // 345: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest - 93, // 346: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest - 97, // 347: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest - 99, // 348: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest - 105, // 349: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame - 106, // 350: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput - 113, // 351: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest - 114, // 352: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest - 115, // 353: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest - 120, // 354: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest - 121, // 355: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest - 145, // 356: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest - 147, // 357: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest - 149, // 358: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest - 116, // 359: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest - 133, // 360: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest - 135, // 361: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest - 137, // 362: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest - 139, // 363: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest - 117, // 364: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest - 152, // 365: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest - 290, // 366: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest - 291, // 367: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest - 160, // 368: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest - 170, // 369: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest - 172, // 370: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest - 174, // 371: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest - 247, // 372: openshell.v1.OpenShell.ReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest - 84, // 373: openshell.v1.OpenShell.ReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest - 177, // 374: openshell.v1.OpenShell.ReportSandboxConfiguration:input_type -> openshell.v1.ReportSandboxConfigurationRequest - 154, // 375: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest - 158, // 376: openshell.v1.OpenShell.ExchangeProviderSubjectToken:input_type -> openshell.v1.ExchangeProviderSubjectTokenRequest - 180, // 377: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest - 181, // 378: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest - 184, // 379: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage - 191, // 380: openshell.v1.OpenShell.ReportMainProcessExit:input_type -> openshell.v1.ReportMainProcessExitRequest - 193, // 381: openshell.v1.OpenShell.FinalizeMainProcessExit:input_type -> openshell.v1.FinalizeMainProcessExitRequest - 199, // 382: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame - 201, // 383: openshell.v1.OpenShell.PeerRelay:input_type -> openshell.v1.PeerRelayFrame - 84, // 384: openshell.v1.OpenShell.PeerReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest - 247, // 385: openshell.v1.OpenShell.PeerReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest - 82, // 386: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest - 109, // 387: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest - 210, // 388: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest - 212, // 389: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest - 214, // 390: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest - 216, // 391: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest - 219, // 392: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest - 221, // 393: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest - 223, // 394: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest - 225, // 395: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest - 227, // 396: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest - 20, // 397: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest - 22, // 398: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest - 230, // 399: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest - 232, // 400: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest - 234, // 401: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest - 236, // 402: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest - 239, // 403: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest - 241, // 404: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest - 243, // 405: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest - 25, // 406: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse - 27, // 407: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse - 29, // 408: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse - 70, // 409: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse - 61, // 410: openshell.v1.OpenShell.BeginRootfsTarStaging:output_type -> openshell.v1.BeginRootfsTarStagingResponse - 70, // 411: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse - 71, // 412: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse - 57, // 413: openshell.v1.OpenShell.CreateSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse - 57, // 414: openshell.v1.OpenShell.GetSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse - 58, // 415: openshell.v1.OpenShell.ListSandboxTemplates:output_type -> openshell.v1.ListSandboxTemplatesResponse - 59, // 416: openshell.v1.OpenShell.DeleteSandboxTemplate:output_type -> openshell.v1.DeleteSandboxTemplateResponse - 72, // 417: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse - 73, // 418: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse - 74, // 419: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse - 83, // 420: openshell.v1.OpenShell.GetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse - 86, // 421: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse - 70, // 422: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse - 70, // 423: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse - 88, // 424: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse - 96, // 425: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse - 96, // 426: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse - 92, // 427: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse - 94, // 428: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse - 98, // 429: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse - 103, // 430: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent - 105, // 431: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame - 103, // 432: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent - 118, // 433: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse - 118, // 434: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse - 119, // 435: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse - 144, // 436: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse - 143, // 437: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse - 146, // 438: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse - 148, // 439: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse - 150, // 440: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse - 118, // 441: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse - 134, // 442: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse - 136, // 443: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse - 138, // 444: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse - 140, // 445: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse - 151, // 446: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse - 153, // 447: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse - 292, // 448: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse - 293, // 449: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse - 169, // 450: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse - 171, // 451: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse - 173, // 452: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse - 175, // 453: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse - 248, // 454: openshell.v1.OpenShell.ReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse - 85, // 455: openshell.v1.OpenShell.ReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse - 178, // 456: openshell.v1.OpenShell.ReportSandboxConfiguration:output_type -> openshell.v1.ReportSandboxConfigurationResponse - 157, // 457: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse - 159, // 458: openshell.v1.OpenShell.ExchangeProviderSubjectToken:output_type -> openshell.v1.ExchangeProviderSubjectTokenResponse - 183, // 459: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse - 182, // 460: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse - 185, // 461: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage - 192, // 462: openshell.v1.OpenShell.ReportMainProcessExit:output_type -> openshell.v1.ReportMainProcessExitResponse - 194, // 463: openshell.v1.OpenShell.FinalizeMainProcessExit:output_type -> openshell.v1.FinalizeMainProcessExitResponse - 199, // 464: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame - 201, // 465: openshell.v1.OpenShell.PeerRelay:output_type -> openshell.v1.PeerRelayFrame - 85, // 466: openshell.v1.OpenShell.PeerReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse - 248, // 467: openshell.v1.OpenShell.PeerReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse - 83, // 468: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse - 110, // 469: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent - 211, // 470: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse - 213, // 471: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse - 215, // 472: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse - 217, // 473: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse - 220, // 474: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse - 222, // 475: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse - 224, // 476: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse - 226, // 477: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse - 229, // 478: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse - 21, // 479: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse - 23, // 480: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse - 231, // 481: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse - 233, // 482: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse - 235, // 483: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse - 237, // 484: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse - 240, // 485: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse - 242, // 486: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse - 244, // 487: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse - 406, // [406:488] is the sub-list for method output_type - 324, // [324:406] is the sub-list for method input_type - 324, // [324:324] is the sub-list for extension type_name - 324, // [324:324] is the sub-list for extension extendee - 0, // [0:324] is the sub-list for field type_name + 282, // 213: openshell.v1.GetSandboxProviderEnvironmentResponse.files:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry + 11, // 214: openshell.v1.ProviderEnvironmentValue.classification:type_name -> openshell.v1.ProviderEnvironmentValueClassification + 157, // 215: openshell.v1.ProviderEnvironmentValue.static_credential_binding:type_name -> openshell.v1.StaticCredentialBinding + 289, // 216: openshell.v1.ProviderEnvironmentValue.expiration_time:type_name -> google.protobuf.Timestamp + 159, // 217: openshell.v1.ProviderEnvironmentSnapshot.values:type_name -> openshell.v1.ProviderEnvironmentValue + 283, // 218: openshell.v1.ProviderEnvironmentSnapshot.dynamic_credentials:type_name -> openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry + 4, // 219: openshell.v1.ProviderEnvironmentSnapshot.readiness_reason:type_name -> openshell.v1.ProviderReadinessReason + 284, // 220: openshell.v1.ProviderEnvironmentSnapshot.files:type_name -> openshell.v1.ProviderEnvironmentSnapshot.FilesEntry + 293, // 221: openshell.v1.ExchangeProviderSubjectTokenResponse.expires_after:type_name -> google.protobuf.Duration + 294, // 222: openshell.v1.UpdateConfigRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 291, // 223: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 299, // 224: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue + 164, // 225: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation + 285, // 226: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry + 165, // 227: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule + 166, // 228: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint + 167, // 229: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule + 169, // 230: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules + 170, // 231: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules + 171, // 232: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary + 300, // 233: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 298, // 234: openshell.v1.L7RuleTarget.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 301, // 235: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule + 168, // 236: openshell.v1.AddDenyRules.target:type_name -> openshell.v1.L7RuleTarget + 302, // 237: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule + 168, // 238: openshell.v1.AddAllowRules.target:type_name -> openshell.v1.L7RuleTarget + 286, // 239: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry + 294, // 240: openshell.v1.GetSandboxPolicyStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 182, // 241: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision + 294, // 242: openshell.v1.ListSandboxPoliciesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 182, // 243: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision + 13, // 244: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus + 12, // 245: openshell.v1.SandboxConfigurationAdmission.state:type_name -> openshell.v1.ConfigurationAdmissionState + 179, // 246: openshell.v1.ReportSandboxConfigurationRequest.admission:type_name -> openshell.v1.SandboxConfigurationAdmission + 13, // 247: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus + 289, // 248: openshell.v1.SandboxPolicyRevision.created_time:type_name -> google.protobuf.Timestamp + 289, // 249: openshell.v1.SandboxPolicyRevision.loaded_time:type_name -> google.protobuf.Timestamp + 291, // 250: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 287, // 251: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry + 294, // 252: openshell.v1.GetSandboxLogsRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 289, // 253: openshell.v1.GetSandboxLogsRequest.since_time:type_name -> google.protobuf.Timestamp + 112, // 254: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine + 112, // 255: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine + 189, // 256: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello + 198, // 257: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat + 214, // 258: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult + 215, // 259: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose + 195, // 260: openshell.v1.SupervisorMessage.config_update_result:type_name -> openshell.v1.ConfigUpdateResult + 196, // 261: openshell.v1.SupervisorMessage.config_bootstrap_result:type_name -> openshell.v1.ConfigBootstrapResult + 190, // 262: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted + 197, // 263: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected + 199, // 264: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat + 204, // 265: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen + 215, // 266: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose + 192, // 267: openshell.v1.GatewayMessage.config_update:type_name -> openshell.v1.ConfigUpdate + 191, // 268: openshell.v1.SessionAccepted.bootstrap:type_name -> openshell.v1.ConfigBootstrap + 293, // 269: openshell.v1.SessionAccepted.heartbeat_interval:type_name -> google.protobuf.Duration + 303, // 270: openshell.v1.ConfigBootstrap.sandbox_config:type_name -> openshell.sandbox.v1.SandboxConfigSnapshot + 160, // 271: openshell.v1.ConfigBootstrap.provider_environment:type_name -> openshell.v1.ProviderEnvironmentSnapshot + 303, // 272: openshell.v1.ConfigUpdate.sandbox_config:type_name -> openshell.sandbox.v1.SandboxConfigSnapshot + 160, // 273: openshell.v1.ConfigUpdate.provider_environment:type_name -> openshell.v1.ProviderEnvironmentSnapshot + 5, // 274: openshell.v1.ConfigComponentApplyResult.component:type_name -> openshell.v1.ConfigComponent + 77, // 275: openshell.v1.ConfigComponentApplyResult.requested_revision:type_name -> openshell.v1.ConfigSnapshotRevision + 77, // 276: openshell.v1.ConfigComponentApplyResult.applied_revision:type_name -> openshell.v1.ConfigSnapshotRevision + 6, // 277: openshell.v1.ConfigComponentApplyResult.outcome:type_name -> openshell.v1.ConfigApplyOutcome + 193, // 278: openshell.v1.ConfigComponentApplyResult.failure:type_name -> openshell.v1.ConfigApplyFailure + 194, // 279: openshell.v1.ConfigUpdateResult.result:type_name -> openshell.v1.ConfigComponentApplyResult + 194, // 280: openshell.v1.ConfigBootstrapResult.results:type_name -> openshell.v1.ConfigComponentApplyResult + 205, // 281: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget + 206, // 282: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget + 207, // 283: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit + 204, // 284: openshell.v1.PeerRelayInit.relay_open:type_name -> openshell.v1.RelayOpen + 209, // 285: openshell.v1.PeerRelayFrame.init:type_name -> openshell.v1.PeerRelayInit + 211, // 286: openshell.v1.PeerConfigUpdateHintRequest.sandbox:type_name -> openshell.v1.PeerConfigSandboxTarget + 289, // 287: openshell.v1.DenialSummary.first_seen_time:type_name -> google.protobuf.Timestamp + 289, // 288: openshell.v1.DenialSummary.last_seen_time:type_name -> google.protobuf.Timestamp + 216, // 289: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample + 218, // 290: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount + 300, // 291: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 289, // 292: openshell.v1.PolicyChunk.created_time:type_name -> google.protobuf.Timestamp + 289, // 293: openshell.v1.PolicyChunk.decided_time:type_name -> google.protobuf.Timestamp + 289, // 294: openshell.v1.PolicyChunk.first_seen_time:type_name -> google.protobuf.Timestamp + 289, // 295: openshell.v1.PolicyChunk.last_seen_time:type_name -> google.protobuf.Timestamp + 291, // 296: openshell.v1.PolicyChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 291, // 297: openshell.v1.PolicyChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 294, // 298: openshell.v1.SubmitPolicyAnalysisRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 217, // 299: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary + 220, // 300: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk + 219, // 301: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary + 294, // 302: openshell.v1.GetDraftPolicyRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 220, // 303: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk + 289, // 304: openshell.v1.GetDraftPolicyResponse.last_analyzed_time:type_name -> google.protobuf.Timestamp + 294, // 305: openshell.v1.ApproveDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 306: openshell.v1.RejectDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 307: openshell.v1.ApproveAllDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 230, // 308: openshell.v1.ApproveAllDraftChunksRequest.approvals:type_name -> openshell.v1.DraftChunkApproval + 294, // 309: openshell.v1.EditDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 300, // 310: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 294, // 311: openshell.v1.UndoDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 312: openshell.v1.ClearDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 294, // 313: openshell.v1.GetDraftHistoryRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 289, // 314: openshell.v1.DraftHistoryEntry.event_time:type_name -> google.protobuf.Timestamp + 240, // 315: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry + 288, // 316: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry + 304, // 317: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 304, // 318: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 304, // 319: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace + 18, // 320: openshell.v1.DeleteWorkspaceResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 290, // 321: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 15, // 322: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole + 294, // 323: openshell.v1.AddWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 15, // 324: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole + 250, // 325: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember + 294, // 326: openshell.v1.RemoveWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 18, // 327: openshell.v1.RemoveWorkspaceMemberResponse.outcome:type_name -> openshell.v1.DeletionOutcome + 294, // 328: openshell.v1.ListWorkspaceMembersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 250, // 329: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember + 289, // 330: openshell.v1.ExtensionServiceCredential.expiration_time:type_name -> google.protobuf.Timestamp + 19, // 331: openshell.v1.EndpointObservation.result:type_name -> openshell.v1.EndpointResult + 258, // 332: openshell.v1.ReportEndpointStatusRequest.observations:type_name -> openshell.v1.EndpointObservation + 19, // 333: openshell.v1.EndpointStatus.last_result:type_name -> openshell.v1.EndpointResult + 289, // 334: openshell.v1.EndpointStatus.last_reported_time:type_name -> google.protobuf.Timestamp + 289, // 335: openshell.v1.SandboxProvisioning.configuration_change_time:type_name -> google.protobuf.Timestamp + 289, // 336: openshell.v1.SandboxProvisioning.first_rejection_time:type_name -> google.protobuf.Timestamp + 289, // 337: openshell.v1.SandboxProvisioning.deadline:type_name -> google.protobuf.Timestamp + 289, // 338: openshell.v1.SandboxProvisioning.timeout_time:type_name -> google.protobuf.Timestamp + 289, // 339: openshell.v1.SandboxProvisioning.cleanup_completed_time:type_name -> google.protobuf.Timestamp + 289, // 340: openshell.v1.SandboxProvisioning.cleanup_retry_time:type_name -> google.protobuf.Timestamp + 289, // 341: openshell.v1.SandboxProvisioning.attachment_change_time:type_name -> google.protobuf.Timestamp + 20, // 342: openshell.v1.SandboxServiceExposure.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode + 289, // 343: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp + 289, // 344: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp + 128, // 345: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential + 157, // 346: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding + 128, // 347: openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential + 25, // 348: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest + 27, // 349: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest + 29, // 350: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest + 53, // 351: openshell.v1.OpenShell.CreateSandbox:input_type -> openshell.v1.CreateSandboxRequest + 61, // 352: openshell.v1.OpenShell.BeginRootfsTarStaging:input_type -> openshell.v1.BeginRootfsTarStagingRequest + 63, // 353: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest + 64, // 354: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest + 54, // 355: openshell.v1.OpenShell.CreateSandboxTemplate:input_type -> openshell.v1.CreateSandboxTemplateRequest + 55, // 356: openshell.v1.OpenShell.GetSandboxTemplate:input_type -> openshell.v1.GetSandboxTemplateRequest + 56, // 357: openshell.v1.OpenShell.ListSandboxTemplates:input_type -> openshell.v1.ListSandboxTemplatesRequest + 57, // 358: openshell.v1.OpenShell.DeleteSandboxTemplate:input_type -> openshell.v1.DeleteSandboxTemplateRequest + 65, // 359: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest + 66, // 360: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest + 67, // 361: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest + 83, // 362: openshell.v1.OpenShell.GetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest + 68, // 363: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest + 69, // 364: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest + 70, // 365: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest + 88, // 366: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest + 90, // 367: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest + 91, // 368: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest + 92, // 369: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest + 94, // 370: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest + 98, // 371: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest + 100, // 372: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest + 106, // 373: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame + 107, // 374: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput + 114, // 375: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest + 115, // 376: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest + 116, // 377: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest + 121, // 378: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest + 122, // 379: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest + 146, // 380: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest + 148, // 381: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest + 150, // 382: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest + 117, // 383: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest + 134, // 384: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest + 136, // 385: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest + 138, // 386: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest + 140, // 387: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest + 118, // 388: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest + 153, // 389: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest + 305, // 390: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest + 306, // 391: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest + 163, // 392: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest + 173, // 393: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest + 175, // 394: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest + 177, // 395: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest + 259, // 396: openshell.v1.OpenShell.ReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest + 85, // 397: openshell.v1.OpenShell.ReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest + 180, // 398: openshell.v1.OpenShell.ReportSandboxConfiguration:input_type -> openshell.v1.ReportSandboxConfigurationRequest + 155, // 399: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest + 161, // 400: openshell.v1.OpenShell.ExchangeProviderSubjectToken:input_type -> openshell.v1.ExchangeProviderSubjectTokenRequest + 183, // 401: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest + 184, // 402: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest + 187, // 403: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage + 200, // 404: openshell.v1.OpenShell.ReportMainProcessExit:input_type -> openshell.v1.ReportMainProcessExitRequest + 202, // 405: openshell.v1.OpenShell.FinalizeMainProcessExit:input_type -> openshell.v1.FinalizeMainProcessExitRequest + 208, // 406: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame + 210, // 407: openshell.v1.OpenShell.PeerRelay:input_type -> openshell.v1.PeerRelayFrame + 85, // 408: openshell.v1.OpenShell.PeerReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest + 259, // 409: openshell.v1.OpenShell.PeerReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest + 83, // 410: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest + 212, // 411: openshell.v1.OpenShell.PeerNotifyConfigUpdate:input_type -> openshell.v1.PeerConfigUpdateHintRequest + 110, // 412: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest + 222, // 413: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest + 224, // 414: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest + 226, // 415: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest + 228, // 416: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest + 231, // 417: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest + 233, // 418: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest + 235, // 419: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest + 237, // 420: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest + 239, // 421: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest + 21, // 422: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest + 23, // 423: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest + 242, // 424: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest + 244, // 425: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest + 246, // 426: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest + 248, // 427: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest + 251, // 428: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest + 253, // 429: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest + 255, // 430: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest + 26, // 431: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse + 28, // 432: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse + 30, // 433: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse + 71, // 434: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse + 62, // 435: openshell.v1.OpenShell.BeginRootfsTarStaging:output_type -> openshell.v1.BeginRootfsTarStagingResponse + 71, // 436: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse + 72, // 437: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse + 58, // 438: openshell.v1.OpenShell.CreateSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse + 58, // 439: openshell.v1.OpenShell.GetSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse + 59, // 440: openshell.v1.OpenShell.ListSandboxTemplates:output_type -> openshell.v1.ListSandboxTemplatesResponse + 60, // 441: openshell.v1.OpenShell.DeleteSandboxTemplate:output_type -> openshell.v1.DeleteSandboxTemplateResponse + 73, // 442: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse + 74, // 443: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse + 75, // 444: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse + 84, // 445: openshell.v1.OpenShell.GetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse + 87, // 446: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse + 71, // 447: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse + 71, // 448: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse + 89, // 449: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse + 97, // 450: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse + 97, // 451: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse + 93, // 452: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse + 95, // 453: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse + 99, // 454: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse + 104, // 455: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent + 106, // 456: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame + 104, // 457: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent + 119, // 458: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse + 119, // 459: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse + 120, // 460: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse + 145, // 461: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse + 144, // 462: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse + 147, // 463: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse + 149, // 464: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse + 151, // 465: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse + 119, // 466: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse + 135, // 467: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse + 137, // 468: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse + 139, // 469: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse + 141, // 470: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse + 152, // 471: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse + 154, // 472: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse + 307, // 473: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse + 308, // 474: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse + 172, // 475: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse + 174, // 476: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse + 176, // 477: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse + 178, // 478: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse + 260, // 479: openshell.v1.OpenShell.ReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse + 86, // 480: openshell.v1.OpenShell.ReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse + 181, // 481: openshell.v1.OpenShell.ReportSandboxConfiguration:output_type -> openshell.v1.ReportSandboxConfigurationResponse + 158, // 482: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse + 162, // 483: openshell.v1.OpenShell.ExchangeProviderSubjectToken:output_type -> openshell.v1.ExchangeProviderSubjectTokenResponse + 186, // 484: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse + 185, // 485: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse + 188, // 486: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage + 201, // 487: openshell.v1.OpenShell.ReportMainProcessExit:output_type -> openshell.v1.ReportMainProcessExitResponse + 203, // 488: openshell.v1.OpenShell.FinalizeMainProcessExit:output_type -> openshell.v1.FinalizeMainProcessExitResponse + 208, // 489: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame + 210, // 490: openshell.v1.OpenShell.PeerRelay:output_type -> openshell.v1.PeerRelayFrame + 86, // 491: openshell.v1.OpenShell.PeerReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse + 260, // 492: openshell.v1.OpenShell.PeerReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse + 84, // 493: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse + 213, // 494: openshell.v1.OpenShell.PeerNotifyConfigUpdate:output_type -> openshell.v1.PeerConfigUpdateHintResponse + 111, // 495: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent + 223, // 496: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse + 225, // 497: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse + 227, // 498: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse + 229, // 499: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse + 232, // 500: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse + 234, // 501: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse + 236, // 502: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse + 238, // 503: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse + 241, // 504: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse + 22, // 505: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse + 24, // 506: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse + 243, // 507: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse + 245, // 508: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse + 247, // 509: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse + 249, // 510: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse + 252, // 511: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse + 254, // 512: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse + 256, // 513: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse + 431, // [431:514] is the sub-list for method output_type + 348, // [348:431] is the sub-list for method input_type + 348, // [348:348] is the sub-list for extension type_name + 348, // [348:348] is the sub-list for extension extendee + 0, // [0:348] is the sub-list for field type_name } func init() { file_openshell_proto_init() } @@ -20322,7 +21365,7 @@ func file_openshell_proto_init() { (*SandboxStreamEvent_Warning)(nil), (*SandboxStreamEvent_DraftPolicyUpdate)(nil), } - file_openshell_proto_msgTypes[141].OneofWrappers = []any{ + file_openshell_proto_msgTypes[143].OneofWrappers = []any{ (*PolicyMergeOperation_AddRule)(nil), (*PolicyMergeOperation_RemoveEndpoint)(nil), (*PolicyMergeOperation_RemoveRule)(nil), @@ -20330,39 +21373,51 @@ func file_openshell_proto_init() { (*PolicyMergeOperation_AddAllowRules)(nil), (*PolicyMergeOperation_RemoveBinary)(nil), } - file_openshell_proto_msgTypes[145].OneofWrappers = []any{} - file_openshell_proto_msgTypes[164].OneofWrappers = []any{ + file_openshell_proto_msgTypes[147].OneofWrappers = []any{} + file_openshell_proto_msgTypes[166].OneofWrappers = []any{ (*SupervisorMessage_Hello)(nil), (*SupervisorMessage_Heartbeat)(nil), (*SupervisorMessage_RelayOpenResult)(nil), (*SupervisorMessage_RelayClose)(nil), + (*SupervisorMessage_ConfigUpdateResult)(nil), + (*SupervisorMessage_ConfigBootstrapResult)(nil), } - file_openshell_proto_msgTypes[165].OneofWrappers = []any{ + file_openshell_proto_msgTypes[167].OneofWrappers = []any{ (*GatewayMessage_SessionAccepted)(nil), (*GatewayMessage_SessionRejected)(nil), (*GatewayMessage_Heartbeat)(nil), (*GatewayMessage_RelayOpen)(nil), (*GatewayMessage_RelayClose)(nil), + (*GatewayMessage_ConfigUpdate)(nil), } - file_openshell_proto_msgTypes[175].OneofWrappers = []any{ + file_openshell_proto_msgTypes[171].OneofWrappers = []any{ + (*ConfigUpdate_SandboxConfig)(nil), + (*ConfigUpdate_ProviderEnvironment)(nil), + } + file_openshell_proto_msgTypes[183].OneofWrappers = []any{ (*RelayOpen_Ssh)(nil), (*RelayOpen_Tcp)(nil), } - file_openshell_proto_msgTypes[179].OneofWrappers = []any{ + file_openshell_proto_msgTypes[187].OneofWrappers = []any{ (*RelayFrame_Init)(nil), (*RelayFrame_Data)(nil), } - file_openshell_proto_msgTypes[181].OneofWrappers = []any{ + file_openshell_proto_msgTypes[189].OneofWrappers = []any{ (*PeerRelayFrame_Init)(nil), (*PeerRelayFrame_Data)(nil), } + file_openshell_proto_msgTypes[191].OneofWrappers = []any{ + (*PeerConfigUpdateHintRequest_Sandbox)(nil), + (*PeerConfigUpdateHintRequest_Workspace)(nil), + (*PeerConfigUpdateHintRequest_AllConnected)(nil), + } 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: 20, - NumMessages: 255, + NumEnums: 21, + NumMessages: 268, 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 d185e24283..f8bccdd30b 100644 --- a/sdk/go/proto/openshellv1/openshell_grpc.pb.go +++ b/sdk/go/proto/openshellv1/openshell_grpc.pb.go @@ -86,6 +86,7 @@ const ( OpenShell_PeerReportProviderReadiness_FullMethodName = "/openshell.v1.OpenShell/PeerReportProviderReadiness" OpenShell_PeerReportEndpointStatus_FullMethodName = "/openshell.v1.OpenShell/PeerReportEndpointStatus" OpenShell_PeerGetSandboxProviderStatus_FullMethodName = "/openshell.v1.OpenShell/PeerGetSandboxProviderStatus" + OpenShell_PeerNotifyConfigUpdate_FullMethodName = "/openshell.v1.OpenShell/PeerNotifyConfigUpdate" OpenShell_WatchSandbox_FullMethodName = "/openshell.v1.OpenShell/WatchSandbox" OpenShell_SubmitPolicyAnalysis_FullMethodName = "/openshell.v1.OpenShell/SubmitPolicyAnalysis" OpenShell_GetDraftPolicy_FullMethodName = "/openshell.v1.OpenShell/GetDraftPolicy" @@ -251,9 +252,10 @@ type OpenShellClient interface { // // The supervisor opens this stream at startup and keeps it alive for the // sandbox lifetime. The gateway uses it to coordinate relay channels for - // SSH connect, ExecSandbox, and targetable sandbox services. Raw service - // bytes flow over RelayStream calls (separate HTTP/2 streams on the same - // connection), not over this stream. + // SSH connect, ExecSandbox, targetable sandbox services, and configuration + // delivery. Peers must report the same exact protocol_revision during the + // handshake. Raw service bytes flow over RelayStream calls (separate HTTP/2 + // streams on the same connection), not over this stream. ConnectSupervisor(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[SupervisorMessage, GatewayMessage], error) // Persist the canonical main process result before the supervisor exits. ReportMainProcessExit(ctx context.Context, in *ReportMainProcessExitRequest, opts ...grpc.CallOption) (*ReportMainProcessExitResponse, error) @@ -283,6 +285,9 @@ type OpenShellClient interface { PeerReportProviderReadiness(ctx context.Context, in *ReportProviderReadinessRequest, opts ...grpc.CallOption) (*ReportProviderReadinessResponse, error) PeerReportEndpointStatus(ctx context.Context, in *ReportEndpointStatusRequest, opts ...grpc.CallOption) (*ReportEndpointStatusResponse, error) PeerGetSandboxProviderStatus(ctx context.Context, in *GetSandboxProviderStatusRequest, opts ...grpc.CallOption) (*GetSandboxProviderStatusResponse, error) + // Best-effort notification to the replica that owns a supervisor session. + // The receiver rebuilds snapshots from authoritative state. + PeerNotifyConfigUpdate(ctx context.Context, in *PeerConfigUpdateHintRequest, opts ...grpc.CallOption) (*PeerConfigUpdateHintResponse, error) // Watch a sandbox and stream updates. // // This stream can include: @@ -1002,6 +1007,16 @@ func (c *openShellClient) PeerGetSandboxProviderStatus(ctx context.Context, in * return out, nil } +func (c *openShellClient) PeerNotifyConfigUpdate(ctx context.Context, in *PeerConfigUpdateHintRequest, opts ...grpc.CallOption) (*PeerConfigUpdateHintResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(PeerConfigUpdateHintResponse) + err := c.cc.Invoke(ctx, OpenShell_PeerNotifyConfigUpdate_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *openShellClient) WatchSandbox(ctx context.Context, in *WatchSandboxRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SandboxStreamEvent], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[7], OpenShell_WatchSandbox_FullMethodName, cOpts...) @@ -1345,9 +1360,10 @@ type OpenShellServer interface { // // The supervisor opens this stream at startup and keeps it alive for the // sandbox lifetime. The gateway uses it to coordinate relay channels for - // SSH connect, ExecSandbox, and targetable sandbox services. Raw service - // bytes flow over RelayStream calls (separate HTTP/2 streams on the same - // connection), not over this stream. + // SSH connect, ExecSandbox, targetable sandbox services, and configuration + // delivery. Peers must report the same exact protocol_revision during the + // handshake. Raw service bytes flow over RelayStream calls (separate HTTP/2 + // streams on the same connection), not over this stream. ConnectSupervisor(grpc.BidiStreamingServer[SupervisorMessage, GatewayMessage]) error // Persist the canonical main process result before the supervisor exits. ReportMainProcessExit(context.Context, *ReportMainProcessExitRequest) (*ReportMainProcessExitResponse, error) @@ -1377,6 +1393,9 @@ type OpenShellServer interface { PeerReportProviderReadiness(context.Context, *ReportProviderReadinessRequest) (*ReportProviderReadinessResponse, error) PeerReportEndpointStatus(context.Context, *ReportEndpointStatusRequest) (*ReportEndpointStatusResponse, error) PeerGetSandboxProviderStatus(context.Context, *GetSandboxProviderStatusRequest) (*GetSandboxProviderStatusResponse, error) + // Best-effort notification to the replica that owns a supervisor session. + // The receiver rebuilds snapshots from authoritative state. + PeerNotifyConfigUpdate(context.Context, *PeerConfigUpdateHintRequest) (*PeerConfigUpdateHintResponse, error) // Watch a sandbox and stream updates. // // This stream can include: @@ -1628,6 +1647,9 @@ func (UnimplementedOpenShellServer) PeerReportEndpointStatus(context.Context, *R func (UnimplementedOpenShellServer) PeerGetSandboxProviderStatus(context.Context, *GetSandboxProviderStatusRequest) (*GetSandboxProviderStatusResponse, error) { return nil, status.Error(codes.Unimplemented, "method PeerGetSandboxProviderStatus not implemented") } +func (UnimplementedOpenShellServer) PeerNotifyConfigUpdate(context.Context, *PeerConfigUpdateHintRequest) (*PeerConfigUpdateHintResponse, error) { + return nil, status.Error(codes.Unimplemented, "method PeerNotifyConfigUpdate not implemented") +} func (UnimplementedOpenShellServer) WatchSandbox(*WatchSandboxRequest, grpc.ServerStreamingServer[SandboxStreamEvent]) error { return status.Error(codes.Unimplemented, "method WatchSandbox not implemented") } @@ -2767,6 +2789,24 @@ func _OpenShell_PeerGetSandboxProviderStatus_Handler(srv interface{}, ctx contex return interceptor(ctx, in, info, handler) } +func _OpenShell_PeerNotifyConfigUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeerConfigUpdateHintRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(OpenShellServer).PeerNotifyConfigUpdate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: OpenShell_PeerNotifyConfigUpdate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(OpenShellServer).PeerNotifyConfigUpdate(ctx, req.(*PeerConfigUpdateHintRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _OpenShell_WatchSandbox_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(WatchSandboxRequest) if err := stream.RecvMsg(m); err != nil { @@ -3333,6 +3373,10 @@ var OpenShell_ServiceDesc = grpc.ServiceDesc{ MethodName: "PeerGetSandboxProviderStatus", Handler: _OpenShell_PeerGetSandboxProviderStatus_Handler, }, + { + MethodName: "PeerNotifyConfigUpdate", + Handler: _OpenShell_PeerNotifyConfigUpdate_Handler, + }, { MethodName: "SubmitPolicyAnalysis", Handler: _OpenShell_SubmitPolicyAnalysis_Handler, diff --git a/sdk/go/proto/sandboxv1/sandbox.pb.go b/sdk/go/proto/sandboxv1/sandbox.pb.go index c38db28c2f..a4b47b6873 100644 --- a/sdk/go/proto/sandboxv1/sandbox.pb.go +++ b/sdk/go/proto/sandboxv1/sandbox.pb.go @@ -248,7 +248,7 @@ func (SettingScope) EnumDescriptor() ([]byte, []int) { return file_sandbox_proto_rawDescGZIP(), []int{3} } -// Source used for the policy payload in GetSandboxConfigResponse. +// Source used for a sandbox configuration payload. type PolicySource int32 const ( @@ -1970,6 +1970,171 @@ func (x *EffectiveSetting) GetScope() SettingScope { return SettingScope_SETTING_SCOPE_UNSPECIFIED } +// Complete effective sandbox configuration delivered to a supervisor. +type SandboxConfigSnapshot struct { + state protoimpl.MessageState `protogen:"open.v1"` + Policy *SandboxPolicy `protobuf:"bytes,1,opt,name=policy,proto3" json:"policy,omitempty"` + Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` + PolicyHash string `protobuf:"bytes,3,opt,name=policy_hash,json=policyHash,proto3" json:"policy_hash,omitempty"` + Settings map[string]*EffectiveSetting `protobuf:"bytes,4,rep,name=settings,proto3" json:"settings,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ConfigRevision uint64 `protobuf:"varint,5,opt,name=config_revision,json=configRevision,proto3" json:"config_revision,omitempty"` + PolicySource PolicySource `protobuf:"varint,6,opt,name=policy_source,json=policySource,proto3,enum=openshell.sandbox.v1.PolicySource" json:"policy_source,omitempty"` + GlobalPolicyVersion uint32 `protobuf:"varint,7,opt,name=global_policy_version,json=globalPolicyVersion,proto3" json:"global_policy_version,omitempty"` + ProviderEnvRevision uint64 `protobuf:"varint,8,opt,name=provider_env_revision,json=providerEnvRevision,proto3" json:"provider_env_revision,omitempty"` + SupervisorMiddlewareServices []*SupervisorMiddlewareService `protobuf:"bytes,9,rep,name=supervisor_middleware_services,json=supervisorMiddlewareServices,proto3" json:"supervisor_middleware_services,omitempty"` + Workspace string `protobuf:"bytes,10,opt,name=workspace,proto3" json:"workspace,omitempty"` + PolicyValidationFailureMode string `protobuf:"bytes,11,opt,name=policy_validation_failure_mode,json=policyValidationFailureMode,proto3" json:"policy_validation_failure_mode,omitempty"` + ExtensionAuthenticationEnabled bool `protobuf:"varint,12,opt,name=extension_authentication_enabled,json=extensionAuthenticationEnabled,proto3" json:"extension_authentication_enabled,omitempty"` + ConfigurationAdmitted bool `protobuf:"varint,13,opt,name=configuration_admitted,json=configurationAdmitted,proto3" json:"configuration_admitted,omitempty"` + ProviderAttachmentEpoch string `protobuf:"bytes,14,opt,name=provider_attachment_epoch,json=providerAttachmentEpoch,proto3" json:"provider_attachment_epoch,omitempty"` + ConfigurationInstanceId string `protobuf:"bytes,15,opt,name=configuration_instance_id,json=configurationInstanceId,proto3" json:"configuration_instance_id,omitempty"` + ConfigurationError string `protobuf:"bytes,16,opt,name=configuration_error,json=configurationError,proto3" json:"configuration_error,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SandboxConfigSnapshot) Reset() { + *x = SandboxConfigSnapshot{} + mi := &file_sandbox_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SandboxConfigSnapshot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SandboxConfigSnapshot) ProtoMessage() {} + +func (x *SandboxConfigSnapshot) ProtoReflect() protoreflect.Message { + mi := &file_sandbox_proto_msgTypes[21] + 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 SandboxConfigSnapshot.ProtoReflect.Descriptor instead. +func (*SandboxConfigSnapshot) Descriptor() ([]byte, []int) { + return file_sandbox_proto_rawDescGZIP(), []int{21} +} + +func (x *SandboxConfigSnapshot) GetPolicy() *SandboxPolicy { + if x != nil { + return x.Policy + } + return nil +} + +func (x *SandboxConfigSnapshot) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *SandboxConfigSnapshot) GetPolicyHash() string { + if x != nil { + return x.PolicyHash + } + return "" +} + +func (x *SandboxConfigSnapshot) GetSettings() map[string]*EffectiveSetting { + if x != nil { + return x.Settings + } + return nil +} + +func (x *SandboxConfigSnapshot) GetConfigRevision() uint64 { + if x != nil { + return x.ConfigRevision + } + return 0 +} + +func (x *SandboxConfigSnapshot) GetPolicySource() PolicySource { + if x != nil { + return x.PolicySource + } + return PolicySource_POLICY_SOURCE_UNSPECIFIED +} + +func (x *SandboxConfigSnapshot) GetGlobalPolicyVersion() uint32 { + if x != nil { + return x.GlobalPolicyVersion + } + return 0 +} + +func (x *SandboxConfigSnapshot) GetProviderEnvRevision() uint64 { + if x != nil { + return x.ProviderEnvRevision + } + return 0 +} + +func (x *SandboxConfigSnapshot) GetSupervisorMiddlewareServices() []*SupervisorMiddlewareService { + if x != nil { + return x.SupervisorMiddlewareServices + } + return nil +} + +func (x *SandboxConfigSnapshot) GetWorkspace() string { + if x != nil { + return x.Workspace + } + return "" +} + +func (x *SandboxConfigSnapshot) GetPolicyValidationFailureMode() string { + if x != nil { + return x.PolicyValidationFailureMode + } + return "" +} + +func (x *SandboxConfigSnapshot) GetExtensionAuthenticationEnabled() bool { + if x != nil { + return x.ExtensionAuthenticationEnabled + } + return false +} + +func (x *SandboxConfigSnapshot) GetConfigurationAdmitted() bool { + if x != nil { + return x.ConfigurationAdmitted + } + return false +} + +func (x *SandboxConfigSnapshot) GetProviderAttachmentEpoch() string { + if x != nil { + return x.ProviderAttachmentEpoch + } + return "" +} + +func (x *SandboxConfigSnapshot) GetConfigurationInstanceId() string { + if x != nil { + return x.ConfigurationInstanceId + } + return "" +} + +func (x *SandboxConfigSnapshot) GetConfigurationError() string { + if x != nil { + return x.ConfigurationError + } + return "" +} + // Response containing effective sandbox settings and policy. type GetSandboxConfigResponse struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -2022,7 +2187,7 @@ type GetSandboxConfigResponse struct { func (x *GetSandboxConfigResponse) Reset() { *x = GetSandboxConfigResponse{} - mi := &file_sandbox_proto_msgTypes[21] + mi := &file_sandbox_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2034,7 +2199,7 @@ func (x *GetSandboxConfigResponse) String() string { func (*GetSandboxConfigResponse) ProtoMessage() {} func (x *GetSandboxConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_sandbox_proto_msgTypes[21] + mi := &file_sandbox_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2047,7 +2212,7 @@ func (x *GetSandboxConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxConfigResponse.ProtoReflect.Descriptor instead. func (*GetSandboxConfigResponse) Descriptor() ([]byte, []int) { - return file_sandbox_proto_rawDescGZIP(), []int{21} + return file_sandbox_proto_rawDescGZIP(), []int{22} } func (x *GetSandboxConfigResponse) GetPolicy() *SandboxPolicy { @@ -2194,7 +2359,7 @@ type SupervisorMiddlewareService struct { func (x *SupervisorMiddlewareService) Reset() { *x = SupervisorMiddlewareService{} - mi := &file_sandbox_proto_msgTypes[22] + mi := &file_sandbox_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2206,7 +2371,7 @@ func (x *SupervisorMiddlewareService) String() string { func (*SupervisorMiddlewareService) ProtoMessage() {} func (x *SupervisorMiddlewareService) ProtoReflect() protoreflect.Message { - mi := &file_sandbox_proto_msgTypes[22] + mi := &file_sandbox_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2219,7 +2384,7 @@ func (x *SupervisorMiddlewareService) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorMiddlewareService.ProtoReflect.Descriptor instead. func (*SupervisorMiddlewareService) Descriptor() ([]byte, []int) { - return file_sandbox_proto_rawDescGZIP(), []int{22} + return file_sandbox_proto_rawDescGZIP(), []int{23} } func (x *SupervisorMiddlewareService) GetName() string { @@ -2424,7 +2589,29 @@ const file_sandbox_proto_rawDesc = "" + "\x05value\"\x86\x01\n" + "\x10EffectiveSetting\x128\n" + "\x05value\x18\x01 \x01(\v2\".openshell.sandbox.v1.SettingValueR\x05value\x128\n" + - "\x05scope\x18\x02 \x01(\x0e2\".openshell.sandbox.v1.SettingScopeR\x05scope\"\xb1\b\n" + + "\x05scope\x18\x02 \x01(\x0e2\".openshell.sandbox.v1.SettingScopeR\x05scope\"\xab\b\n" + + "\x15SandboxConfigSnapshot\x12;\n" + + "\x06policy\x18\x01 \x01(\v2#.openshell.sandbox.v1.SandboxPolicyR\x06policy\x12\x18\n" + + "\aversion\x18\x02 \x01(\rR\aversion\x12\x1f\n" + + "\vpolicy_hash\x18\x03 \x01(\tR\n" + + "policyHash\x12U\n" + + "\bsettings\x18\x04 \x03(\v29.openshell.sandbox.v1.SandboxConfigSnapshot.SettingsEntryR\bsettings\x12'\n" + + "\x0fconfig_revision\x18\x05 \x01(\x04R\x0econfigRevision\x12G\n" + + "\rpolicy_source\x18\x06 \x01(\x0e2\".openshell.sandbox.v1.PolicySourceR\fpolicySource\x122\n" + + "\x15global_policy_version\x18\a \x01(\rR\x13globalPolicyVersion\x122\n" + + "\x15provider_env_revision\x18\b \x01(\x04R\x13providerEnvRevision\x12w\n" + + "\x1esupervisor_middleware_services\x18\t \x03(\v21.openshell.sandbox.v1.SupervisorMiddlewareServiceR\x1csupervisorMiddlewareServices\x12\x1c\n" + + "\tworkspace\x18\n" + + " \x01(\tR\tworkspace\x12C\n" + + "\x1epolicy_validation_failure_mode\x18\v \x01(\tR\x1bpolicyValidationFailureMode\x12H\n" + + " extension_authentication_enabled\x18\f \x01(\bR\x1eextensionAuthenticationEnabled\x125\n" + + "\x16configuration_admitted\x18\r \x01(\bR\x15configurationAdmitted\x12:\n" + + "\x19provider_attachment_epoch\x18\x0e \x01(\tR\x17providerAttachmentEpoch\x12:\n" + + "\x19configuration_instance_id\x18\x0f \x01(\tR\x17configurationInstanceId\x12/\n" + + "\x13configuration_error\x18\x10 \x01(\tR\x12configurationError\x1ac\n" + + "\rSettingsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12<\n" + + "\x05value\x18\x02 \x01(\v2&.openshell.sandbox.v1.EffectiveSettingR\x05value:\x028\x01\"\xb1\b\n" + "\x18GetSandboxConfigResponse\x12;\n" + "\x06policy\x18\x01 \x01(\v2#.openshell.sandbox.v1.SandboxPolicyR\x06policy\x12\x18\n" + "\aversion\x18\x02 \x01(\rR\aversion\x12\x1f\n" + @@ -2491,7 +2678,7 @@ func file_sandbox_proto_rawDescGZIP() []byte { } var file_sandbox_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_sandbox_proto_msgTypes = make([]protoimpl.MessageInfo, 32) +var file_sandbox_proto_msgTypes = make([]protoimpl.MessageInfo, 34) var file_sandbox_proto_goTypes = []any{ (NetworkTlsMode)(0), // 0: openshell.sandbox.v1.NetworkTlsMode (NetworkEnforcementMode)(0), // 1: openshell.sandbox.v1.NetworkEnforcementMode @@ -2519,67 +2706,74 @@ var file_sandbox_proto_goTypes = []any{ (*GetGatewayConfigResponse)(nil), // 23: openshell.sandbox.v1.GetGatewayConfigResponse (*SettingValue)(nil), // 24: openshell.sandbox.v1.SettingValue (*EffectiveSetting)(nil), // 25: openshell.sandbox.v1.EffectiveSetting - (*GetSandboxConfigResponse)(nil), // 26: openshell.sandbox.v1.GetSandboxConfigResponse - (*SupervisorMiddlewareService)(nil), // 27: openshell.sandbox.v1.SupervisorMiddlewareService - nil, // 28: openshell.sandbox.v1.SandboxPolicy.NetworkPoliciesEntry - nil, // 29: openshell.sandbox.v1.SandboxPolicy.NetworkMiddlewaresEntry - nil, // 30: openshell.sandbox.v1.NetworkEndpoint.GraphqlPersistedQueriesEntry - nil, // 31: openshell.sandbox.v1.L7DenyRule.QueryEntry - nil, // 32: openshell.sandbox.v1.L7DenyRule.ParamsEntry - nil, // 33: openshell.sandbox.v1.L7Allow.QueryEntry - nil, // 34: openshell.sandbox.v1.L7Allow.ParamsEntry - nil, // 35: openshell.sandbox.v1.GetGatewayConfigResponse.SettingsEntry - nil, // 36: openshell.sandbox.v1.GetSandboxConfigResponse.SettingsEntry - (*structpb.Struct)(nil), // 37: google.protobuf.Struct - (*datamodelv1.WorkspaceSelector)(nil), // 38: openshell.datamodel.v1.WorkspaceSelector - (*durationpb.Duration)(nil), // 39: google.protobuf.Duration + (*SandboxConfigSnapshot)(nil), // 26: openshell.sandbox.v1.SandboxConfigSnapshot + (*GetSandboxConfigResponse)(nil), // 27: openshell.sandbox.v1.GetSandboxConfigResponse + (*SupervisorMiddlewareService)(nil), // 28: openshell.sandbox.v1.SupervisorMiddlewareService + nil, // 29: openshell.sandbox.v1.SandboxPolicy.NetworkPoliciesEntry + nil, // 30: openshell.sandbox.v1.SandboxPolicy.NetworkMiddlewaresEntry + nil, // 31: openshell.sandbox.v1.NetworkEndpoint.GraphqlPersistedQueriesEntry + nil, // 32: openshell.sandbox.v1.L7DenyRule.QueryEntry + nil, // 33: openshell.sandbox.v1.L7DenyRule.ParamsEntry + nil, // 34: openshell.sandbox.v1.L7Allow.QueryEntry + nil, // 35: openshell.sandbox.v1.L7Allow.ParamsEntry + nil, // 36: openshell.sandbox.v1.GetGatewayConfigResponse.SettingsEntry + nil, // 37: openshell.sandbox.v1.SandboxConfigSnapshot.SettingsEntry + nil, // 38: openshell.sandbox.v1.GetSandboxConfigResponse.SettingsEntry + (*structpb.Struct)(nil), // 39: google.protobuf.Struct + (*datamodelv1.WorkspaceSelector)(nil), // 40: openshell.datamodel.v1.WorkspaceSelector + (*durationpb.Duration)(nil), // 41: google.protobuf.Duration } var file_sandbox_proto_depIdxs = []int32{ 6, // 0: openshell.sandbox.v1.SandboxPolicy.filesystem:type_name -> openshell.sandbox.v1.FilesystemPolicy 7, // 1: openshell.sandbox.v1.SandboxPolicy.landlock:type_name -> openshell.sandbox.v1.LandlockPolicy 8, // 2: openshell.sandbox.v1.SandboxPolicy.process:type_name -> openshell.sandbox.v1.ProcessPolicy - 28, // 3: openshell.sandbox.v1.SandboxPolicy.network_policies:type_name -> openshell.sandbox.v1.SandboxPolicy.NetworkPoliciesEntry - 29, // 4: openshell.sandbox.v1.SandboxPolicy.network_middlewares:type_name -> openshell.sandbox.v1.SandboxPolicy.NetworkMiddlewaresEntry + 29, // 3: openshell.sandbox.v1.SandboxPolicy.network_policies:type_name -> openshell.sandbox.v1.SandboxPolicy.NetworkPoliciesEntry + 30, // 4: openshell.sandbox.v1.SandboxPolicy.network_middlewares:type_name -> openshell.sandbox.v1.SandboxPolicy.NetworkMiddlewaresEntry 13, // 5: openshell.sandbox.v1.NetworkPolicyRule.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint 20, // 6: openshell.sandbox.v1.NetworkPolicyRule.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 37, // 7: openshell.sandbox.v1.NetworkMiddlewareConfig.config:type_name -> google.protobuf.Struct + 39, // 7: openshell.sandbox.v1.NetworkMiddlewareConfig.config:type_name -> google.protobuf.Struct 11, // 8: openshell.sandbox.v1.NetworkMiddlewareConfig.endpoints:type_name -> openshell.sandbox.v1.MiddlewareEndpointSelector 0, // 9: openshell.sandbox.v1.NetworkEndpoint.tls:type_name -> openshell.sandbox.v1.NetworkTlsMode 1, // 10: openshell.sandbox.v1.NetworkEndpoint.enforcement:type_name -> openshell.sandbox.v1.NetworkEnforcementMode 2, // 11: openshell.sandbox.v1.NetworkEndpoint.access:type_name -> openshell.sandbox.v1.NetworkAccessPreset 17, // 12: openshell.sandbox.v1.NetworkEndpoint.rules:type_name -> openshell.sandbox.v1.L7Rule 16, // 13: openshell.sandbox.v1.NetworkEndpoint.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule - 30, // 14: openshell.sandbox.v1.NetworkEndpoint.graphql_persisted_queries:type_name -> openshell.sandbox.v1.NetworkEndpoint.GraphqlPersistedQueriesEntry + 31, // 14: openshell.sandbox.v1.NetworkEndpoint.graphql_persisted_queries:type_name -> openshell.sandbox.v1.NetworkEndpoint.GraphqlPersistedQueriesEntry 14, // 15: openshell.sandbox.v1.NetworkEndpoint.mcp:type_name -> openshell.sandbox.v1.McpOptions 12, // 16: openshell.sandbox.v1.NetworkEndpoint.credential_binding:type_name -> openshell.sandbox.v1.NetworkCredentialBinding - 31, // 17: openshell.sandbox.v1.L7DenyRule.query:type_name -> openshell.sandbox.v1.L7DenyRule.QueryEntry - 32, // 18: openshell.sandbox.v1.L7DenyRule.params:type_name -> openshell.sandbox.v1.L7DenyRule.ParamsEntry + 32, // 17: openshell.sandbox.v1.L7DenyRule.query:type_name -> openshell.sandbox.v1.L7DenyRule.QueryEntry + 33, // 18: openshell.sandbox.v1.L7DenyRule.params:type_name -> openshell.sandbox.v1.L7DenyRule.ParamsEntry 18, // 19: openshell.sandbox.v1.L7Rule.allow:type_name -> openshell.sandbox.v1.L7Allow - 33, // 20: openshell.sandbox.v1.L7Allow.query:type_name -> openshell.sandbox.v1.L7Allow.QueryEntry - 34, // 21: openshell.sandbox.v1.L7Allow.params:type_name -> openshell.sandbox.v1.L7Allow.ParamsEntry - 38, // 22: openshell.sandbox.v1.GetSandboxConfigRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 35, // 23: openshell.sandbox.v1.GetGatewayConfigResponse.settings:type_name -> openshell.sandbox.v1.GetGatewayConfigResponse.SettingsEntry + 34, // 20: openshell.sandbox.v1.L7Allow.query:type_name -> openshell.sandbox.v1.L7Allow.QueryEntry + 35, // 21: openshell.sandbox.v1.L7Allow.params:type_name -> openshell.sandbox.v1.L7Allow.ParamsEntry + 40, // 22: openshell.sandbox.v1.GetSandboxConfigRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 36, // 23: openshell.sandbox.v1.GetGatewayConfigResponse.settings:type_name -> openshell.sandbox.v1.GetGatewayConfigResponse.SettingsEntry 24, // 24: openshell.sandbox.v1.EffectiveSetting.value:type_name -> openshell.sandbox.v1.SettingValue 3, // 25: openshell.sandbox.v1.EffectiveSetting.scope:type_name -> openshell.sandbox.v1.SettingScope - 5, // 26: openshell.sandbox.v1.GetSandboxConfigResponse.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 36, // 27: openshell.sandbox.v1.GetSandboxConfigResponse.settings:type_name -> openshell.sandbox.v1.GetSandboxConfigResponse.SettingsEntry - 4, // 28: openshell.sandbox.v1.GetSandboxConfigResponse.policy_source:type_name -> openshell.sandbox.v1.PolicySource - 27, // 29: openshell.sandbox.v1.GetSandboxConfigResponse.supervisor_middleware_services:type_name -> openshell.sandbox.v1.SupervisorMiddlewareService - 39, // 30: openshell.sandbox.v1.SupervisorMiddlewareService.request_timeout:type_name -> google.protobuf.Duration - 9, // 31: openshell.sandbox.v1.SandboxPolicy.NetworkPoliciesEntry.value:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 10, // 32: openshell.sandbox.v1.SandboxPolicy.NetworkMiddlewaresEntry.value:type_name -> openshell.sandbox.v1.NetworkMiddlewareConfig - 15, // 33: openshell.sandbox.v1.NetworkEndpoint.GraphqlPersistedQueriesEntry.value:type_name -> openshell.sandbox.v1.GraphqlOperation - 19, // 34: openshell.sandbox.v1.L7DenyRule.QueryEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher - 19, // 35: openshell.sandbox.v1.L7DenyRule.ParamsEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher - 19, // 36: openshell.sandbox.v1.L7Allow.QueryEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher - 19, // 37: openshell.sandbox.v1.L7Allow.ParamsEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher - 24, // 38: openshell.sandbox.v1.GetGatewayConfigResponse.SettingsEntry.value:type_name -> openshell.sandbox.v1.SettingValue - 25, // 39: openshell.sandbox.v1.GetSandboxConfigResponse.SettingsEntry.value:type_name -> openshell.sandbox.v1.EffectiveSetting - 40, // [40:40] is the sub-list for method output_type - 40, // [40:40] is the sub-list for method input_type - 40, // [40:40] is the sub-list for extension type_name - 40, // [40:40] is the sub-list for extension extendee - 0, // [0:40] is the sub-list for field type_name + 5, // 26: openshell.sandbox.v1.SandboxConfigSnapshot.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 37, // 27: openshell.sandbox.v1.SandboxConfigSnapshot.settings:type_name -> openshell.sandbox.v1.SandboxConfigSnapshot.SettingsEntry + 4, // 28: openshell.sandbox.v1.SandboxConfigSnapshot.policy_source:type_name -> openshell.sandbox.v1.PolicySource + 28, // 29: openshell.sandbox.v1.SandboxConfigSnapshot.supervisor_middleware_services:type_name -> openshell.sandbox.v1.SupervisorMiddlewareService + 5, // 30: openshell.sandbox.v1.GetSandboxConfigResponse.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 38, // 31: openshell.sandbox.v1.GetSandboxConfigResponse.settings:type_name -> openshell.sandbox.v1.GetSandboxConfigResponse.SettingsEntry + 4, // 32: openshell.sandbox.v1.GetSandboxConfigResponse.policy_source:type_name -> openshell.sandbox.v1.PolicySource + 28, // 33: openshell.sandbox.v1.GetSandboxConfigResponse.supervisor_middleware_services:type_name -> openshell.sandbox.v1.SupervisorMiddlewareService + 41, // 34: openshell.sandbox.v1.SupervisorMiddlewareService.request_timeout:type_name -> google.protobuf.Duration + 9, // 35: openshell.sandbox.v1.SandboxPolicy.NetworkPoliciesEntry.value:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 10, // 36: openshell.sandbox.v1.SandboxPolicy.NetworkMiddlewaresEntry.value:type_name -> openshell.sandbox.v1.NetworkMiddlewareConfig + 15, // 37: openshell.sandbox.v1.NetworkEndpoint.GraphqlPersistedQueriesEntry.value:type_name -> openshell.sandbox.v1.GraphqlOperation + 19, // 38: openshell.sandbox.v1.L7DenyRule.QueryEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher + 19, // 39: openshell.sandbox.v1.L7DenyRule.ParamsEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher + 19, // 40: openshell.sandbox.v1.L7Allow.QueryEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher + 19, // 41: openshell.sandbox.v1.L7Allow.ParamsEntry.value:type_name -> openshell.sandbox.v1.L7QueryMatcher + 24, // 42: openshell.sandbox.v1.GetGatewayConfigResponse.SettingsEntry.value:type_name -> openshell.sandbox.v1.SettingValue + 25, // 43: openshell.sandbox.v1.SandboxConfigSnapshot.SettingsEntry.value:type_name -> openshell.sandbox.v1.EffectiveSetting + 25, // 44: openshell.sandbox.v1.GetSandboxConfigResponse.SettingsEntry.value:type_name -> openshell.sandbox.v1.EffectiveSetting + 45, // [45:45] is the sub-list for method output_type + 45, // [45:45] is the sub-list for method input_type + 45, // [45:45] is the sub-list for extension type_name + 45, // [45:45] is the sub-list for extension extendee + 0, // [0:45] is the sub-list for field type_name } func init() { file_sandbox_proto_init() } @@ -2600,7 +2794,7 @@ func file_sandbox_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_sandbox_proto_rawDesc), len(file_sandbox_proto_rawDesc)), NumEnums: 5, - NumMessages: 32, + NumMessages: 34, NumExtensions: 0, NumServices: 0, }, diff --git a/sdk/typescript/src/raw.ts b/sdk/typescript/src/raw.ts index 1571e8e23e..f8beb69782 100644 --- a/sdk/typescript/src/raw.ts +++ b/sdk/typescript/src/raw.ts @@ -8,7 +8,7 @@ export * from './gen/google/rpc/error_details_pb.js'; // OpenShellClient / SandboxClient (`.raw` and `.transport`). These are the // uncurated wire types; import them from '@nvidia/openshell-sdk/raw'. The // curated entry point stays free of generated types so its surface does not -// shift when the proto regenerates. The four generated modules export disjoint +// shift when the proto regenerates. The generated modules export disjoint // symbol names, so a flat re-export is unambiguous. export * from './gen/openshell_pb.js'; export * from './gen/options_pb.js';