From feac6b4be9180b68f566ed1c4894e55949311eb1 Mon Sep 17 00:00:00 2001 From: Taylor Mutch Date: Mon, 26 Oct 2026 15:29:32 -0700 Subject: [PATCH] feat(gateway): expose workspace service route discovery Signed-off-by: Taylor Mutch --- .../tests/ensure_providers_integration.rs | 15 + .../openshell-cli/tests/mtls_integration.rs | 15 + .../tests/provider_commands_integration.rs | 15 + .../sandbox_create_lifecycle_integration.rs | 15 + .../sandbox_exec_streaming_integration.rs | 7 + .../sandbox_name_fallback_integration.rs | 15 + crates/openshell-sdk/tests/client_mock.rs | 14 + crates/openshell-server/README.md | 24 + crates/openshell-server/src/grpc/mod.rs | 17 + .../src/grpc/service_advertisement.rs | 3 +- .../src/grpc/service_discovery.rs | 586 ++++++++ crates/openshell-server/src/lib.rs | 3 + crates/openshell-server/src/storage_proto.rs | 10 +- crates/openshell-server/tests/common/mod.rs | 14 + .../tests/supervisor_relay_integration.rs | 14 + docs/how-it-works/gateways/configuration.mdx | 15 +- proto/openshell.proto | 62 + sdk/go/proto/openshellv1/openshell.pb.go | 1257 +++++++++++------ sdk/go/proto/openshellv1/openshell_grpc.pb.go | 99 +- skills/debug-openshell-cluster/SKILL.md | 13 +- 20 files changed, 1784 insertions(+), 429 deletions(-) create mode 100644 crates/openshell-server/src/grpc/service_discovery.rs diff --git a/crates/openshell-cli/tests/ensure_providers_integration.rs b/crates/openshell-cli/tests/ensure_providers_integration.rs index be3e4f2e49..29be137f18 100644 --- a/crates/openshell-cli/tests/ensure_providers_integration.rs +++ b/crates/openshell-cli/tests/ensure_providers_integration.rs @@ -80,6 +80,21 @@ impl TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = tokio_stream::wrappers::ReceiverStream< + Result, + >; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/mtls_integration.rs b/crates/openshell-cli/tests/mtls_integration.rs index 1017712035..f2b569de96 100644 --- a/crates/openshell-cli/tests/mtls_integration.rs +++ b/crates/openshell-cli/tests/mtls_integration.rs @@ -32,6 +32,21 @@ struct TestOpenShell; #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = tokio_stream::wrappers::ReceiverStream< + Result, + >; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &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 89247ba718..f14805f17d 100644 --- a/crates/openshell-cli/tests/provider_commands_integration.rs +++ b/crates/openshell-cli/tests/provider_commands_integration.rs @@ -235,6 +235,21 @@ impl TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = tokio_stream::wrappers::ReceiverStream< + Result, + >; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &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 db9c02ffaf..762ec13561 100644 --- a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs +++ b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs @@ -101,6 +101,21 @@ struct TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = tokio_stream::wrappers::ReceiverStream< + Result, + >; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &self, _request: tonic::Request, diff --git a/crates/openshell-cli/tests/sandbox_exec_streaming_integration.rs b/crates/openshell-cli/tests/sandbox_exec_streaming_integration.rs index 31e67baf0f..4238254ed4 100644 --- a/crates/openshell-cli/tests/sandbox_exec_streaming_integration.rs +++ b/crates/openshell-cli/tests/sandbox_exec_streaming_integration.rs @@ -163,6 +163,13 @@ macro_rules! mock_gateway { ) => { #[tonic::async_trait] impl OpenShell for MockGateway { + async fn get_service_route_snapshot(&self, _: Request) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = tokio_stream::wrappers::ReceiverStream>; + async fn watch_service_routes(&self, _: Request) -> Result, Status> { + Err(Status::unimplemented("unused")) + } $(async fn $method(&self, _: Request<$request>) -> Result, Status> { Err(Status::unimplemented("unused test RPC")) })* diff --git a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs index 497f3ce778..c218a7fcb7 100644 --- a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs +++ b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs @@ -47,6 +47,21 @@ struct TestOpenShell { #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = tokio_stream::wrappers::ReceiverStream< + Result, + >; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &self, _request: tonic::Request, diff --git a/crates/openshell-sdk/tests/client_mock.rs b/crates/openshell-sdk/tests/client_mock.rs index ce7ac3b364..849ac497b1 100644 --- a/crates/openshell-sdk/tests/client_mock.rs +++ b/crates/openshell-sdk/tests/client_mock.rs @@ -236,6 +236,20 @@ fn workload_template_proto(name: &str, workspace: &str) -> proto::SandboxWorkloa #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = + tokio_stream::wrappers::ReceiverStream>; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &self, _request: tonic::Request, diff --git a/crates/openshell-server/README.md b/crates/openshell-server/README.md index 00d30eaac0..195b576190 100644 --- a/crates/openshell-server/README.md +++ b/crates/openshell-server/README.md @@ -206,3 +206,27 @@ change durable sandbox protobufs. Reads revalidate owner, configuration, generation, and expiry. Cleanup scans bounded pages and uses conditional deletes so concurrent renewals are preserved. Discovery consumers must not treat these records as application health or external ingress readiness. + +## Workspace service discovery + +`GetServiceRouteSnapshot` and `WatchServiceRoutes` expose accepted installations +for one explicit active workspace. They require `sandbox:read` and workspace +user access; omitted/all-workspaces selectors and sandbox principals are rejected. +Dedicated discovery machine grants are separate work. + +Each successful response replaces the complete view. Consumers preserve the +returned hostname as TLS SNI and HTTP authority when dialing the supervisor +endpoint, remove absent routes, and expire cached entries at `expires_at` even +when discovery is unavailable. An error is not an empty replacement. The opaque +snapshot revision includes lease renewals; `installation_version` remains stable +across those renewals and changes when installation identity changes. These +records establish neither application health nor ingress readiness. + +Collection checks installation resource versions across two scans, retrying once +if changed. This is a verified view, not a transaction across configuration and +owner resources. Reads are bounded to 1,000 installation records, 4,096 routes, +4 MiB, and ten seconds. Overflow, corruption, or storage failure returns an error. +Watches refresh and reauthorize each second, use a one-message buffer, and end +after one minute or a five-second blocked send. Each gateway process accepts at +most 32 watches. Reconnect and relist on stream termination; revisions are opaque +equality tokens, not resumable cursors or an ordering across gateway replicas. diff --git a/crates/openshell-server/src/grpc/mod.rs b/crates/openshell-server/src/grpc/mod.rs index d5b658a12d..8cd3bbe108 100644 --- a/crates/openshell-server/src/grpc/mod.rs +++ b/crates/openshell-server/src/grpc/mod.rs @@ -14,6 +14,7 @@ pub mod supervisor_host; pub use sandbox::mint_persisted_authentication; mod service; pub mod service_advertisement; +mod service_discovery; mod validation; pub mod workspace; @@ -511,6 +512,22 @@ impl OpenShell for OpenShellService { service::handle_list_services(&self.state, request).await } + async fn get_service_route_snapshot( + &self, + request: Request, + ) -> Result, Status> { + service_discovery::get_snapshot(&self.state, request).await + } + + type WatchServiceRoutesStream = service_discovery::RouteWatchStream; + + async fn watch_service_routes( + &self, + request: Request, + ) -> Result, Status> { + service_discovery::watch(&self.state, request).await + } + async fn delete_service( &self, request: Request, diff --git a/crates/openshell-server/src/grpc/service_advertisement.rs b/crates/openshell-server/src/grpc/service_advertisement.rs index 38949d8d85..e7238de593 100644 --- a/crates/openshell-server/src/grpc/service_advertisement.rs +++ b/crates/openshell-server/src/grpc/service_advertisement.rs @@ -495,7 +495,7 @@ pub fn spawn_cleanup(state: Arc, mut shutdown: tokio::sync::watch:: } #[cfg(test)] -mod tests { +pub mod tests { use super::*; fn route() -> SandboxServiceRoute { @@ -635,6 +635,7 @@ mod tests { port: 9443, domain: "services.example.com".into(), }; + Arc::get_mut(&mut state).unwrap().admin_role = "openshell-admin".into(); let sandbox = Sandbox { metadata: Some(ObjectMeta { id: "sandbox".into(), diff --git a/crates/openshell-server/src/grpc/service_discovery.rs b/crates/openshell-server/src/grpc/service_discovery.rs new file mode 100644 index 0000000000..d552833d51 --- /dev/null +++ b/crates/openshell-server/src/grpc/service_discovery.rs @@ -0,0 +1,586 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Bounded, full-replacement workspace views of accepted app installations. + +use std::sync::Arc; +use std::time::Duration; + +use openshell_core::proto::{ + DiscoveredServiceRoute, GetServiceRouteSnapshotRequest, GetServiceRouteSnapshotResponse, + Sandbox, SandboxServiceRoute, ServiceRouteEndpoint, ServiceRouteSnapshot, + WatchServiceRoutesRequest, WatchServiceRoutesResponse, +}; +use openshell_core::{ObjectName, ObjectWorkspace}; +use prost::Message as _; +use tokio_stream::wrappers::ReceiverStream; +use tonic::{Request, Response, Status}; + +use super::service_advertisement::{Installation, OBJECT_TYPE, is_current}; +use crate::ServerState; +use crate::auth::principal::Principal; +use crate::auth::workspace_authz::{ + MinWorkspaceRole, authorize_workspace, selected_workspace_name, +}; +use crate::persistence::{ObjectCursor, ObjectRecord, current_time_ms}; + +const MAX_RECORDS: usize = 1000; +const MAX_ROUTES: usize = 4096; +const MAX_BYTES: usize = 4 * 1024 * 1024; +const SNAPSHOT_TIMEOUT: Duration = Duration::from_secs(10); +const WATCH_LIFETIME: Duration = Duration::from_mins(1); +const REFRESH_INTERVAL: Duration = Duration::from_secs(1); +const SEND_TIMEOUT: Duration = Duration::from_secs(5); +pub type RouteWatchStream = ReceiverStream>; + +async fn authorize( + state: &ServerState, + principal: &Principal, + workspace: &str, +) -> Result<(), Status> { + if !matches!(principal, Principal::User(_) | Principal::Operator(_)) { + return Err(Status::permission_denied( + "service discovery requires a user/API identity", + )); + } + authorize_workspace( + &state.store, + &state.admin_role, + principal, + workspace, + MinWorkspaceRole::User, + ) + .await?; + super::workspace::resolve_workspace(state.store.as_ref(), workspace) + .await? + .ensure_active()?; + Ok(()) +} + +pub async fn get_snapshot( + state: &Arc, + request: Request, +) -> Result, Status> { + let principal = super::extract_principal(&request)?; + let workspace = selected_workspace_name(request.get_ref().workspace_scope.as_ref())?; + authorize(state, &principal, workspace).await?; + Ok(Response::new(GetServiceRouteSnapshotResponse { + snapshot: Some(snapshot(state, workspace).await?), + })) +} + +pub async fn watch( + state: &Arc, + request: Request, +) -> Result, Status> { + let principal = super::extract_principal(&request)?; + let workspace = + selected_workspace_name(request.get_ref().workspace_scope.as_ref())?.to_string(); + authorize(state, &principal, &workspace).await?; + let permit = state + .discovery_watches + .clone() + .try_acquire_owned() + .map_err(|_| Status::resource_exhausted("too many service discovery watches"))?; + let initial = snapshot(state, &workspace).await?; + let mut revision = initial.revision.clone(); + let (tx, rx) = tokio::sync::mpsc::channel(1); + tx.try_send(Ok(WatchServiceRoutesResponse { + snapshot: Some(initial), + })) + .map_err(|_| Status::cancelled("discovery client closed"))?; + let state = state.clone(); + tokio::spawn(async move { + let _permit = permit; + let deadline = tokio::time::Instant::now() + WATCH_LIFETIME; + let mut interval = tokio::time::interval(REFRESH_INTERVAL); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); + interval.tick().await; + loop { + tokio::select! { + () = tx.closed() => return, + () = tokio::time::sleep_until(deadline) => return, + _ = interval.tick() => {} + } + let refresh = async { + authorize(&state, &principal, &workspace).await?; + snapshot(&state, &workspace).await + }; + let result = tokio::select! { + () = tx.closed() => return, + () = tokio::time::sleep_until(deadline) => return, + result = refresh => result, + }; + let message = match result { + Ok(next) if next.revision == revision => continue, + Ok(next) => { + revision.clone_from(&next.revision); + Ok(WatchServiceRoutesResponse { + snapshot: Some(next), + }) + } + Err(error) => Err(error), + }; + let failed = message.is_err(); + let sent = tokio::select! { + () = tx.closed() => return, + () = tokio::time::sleep_until(deadline) => return, + result = tokio::time::timeout(SEND_TIMEOUT, tx.send(message)) => result, + }; + if failed || !matches!(sent, Ok(Ok(()))) { + return; + } + } + }); + Ok(Response::new(ReceiverStream::new(rx))) +} + +async fn records(state: &ServerState, workspace: &str) -> Result, Status> { + let mut records = Vec::new(); + let mut cursor: Option = None; + let mut bytes = 0usize; + loop { + let page = state + .store + .list_after(OBJECT_TYPE, workspace, cursor.as_ref(), 128) + .await + .map_err(|_| Status::unavailable("service installation storage unavailable"))?; + for record in &page { + bytes = bytes.saturating_add(record.payload.len()); + if bytes > MAX_BYTES || records.len() + page.len() > MAX_RECORDS { + return Err(Status::resource_exhausted( + "service discovery collection limit exceeded", + )); + } + } + let full = page.len() == 128; + cursor = page.last().map(ObjectCursor::from); + records.extend(page); + if !full { + break; + } + } + Ok(records) +} + +pub async fn snapshot( + state: &ServerState, + workspace: &str, +) -> Result { + tokio::time::timeout(SNAPSHOT_TIMEOUT, collect(state, workspace)) + .await + .map_err(|_| Status::unavailable("service discovery collection timed out"))? +} + +async fn collect(state: &ServerState, workspace: &str) -> Result { + // Verify the installation collection did not change across the scan. + // This is a bounded verified view, not a cross-resource transaction. + for _ in 0..2 { + let before = records(state, workspace).await?; + let mut routes = Vec::new(); + for object in &before { + let installation: Installation = serde_json::from_slice(&object.payload) + .map_err(|_| Status::internal("invalid service installation record"))?; + if !is_current(state, &installation).await? { + continue; + } + let sandbox = state + .store + .get_message::(&installation.sandbox_id) + .await + .map_err(|_| Status::unavailable("sandbox storage unavailable"))? + .ok_or_else(|| Status::unavailable("sandbox changed during discovery"))?; + if sandbox.object_workspace() != workspace { + return Err(Status::internal("installation workspace mismatch")); + } + for bytes in &installation.routes { + let route = SandboxServiceRoute::decode(bytes.as_slice()) + .map_err(|_| Status::internal("invalid installed service route"))?; + let label = if route.name.is_empty() { + format!("{workspace}--{}", sandbox.object_name()) + } else { + format!("{workspace}--{}--{}", sandbox.object_name(), route.name) + }; + if label.len() > 63 { + return Err(Status::failed_precondition( + "service hostname exceeds DNS label limit", + )); + } + let hostname = format!("{label}.{}", installation.service_domain); + let identity = serde_json::to_vec(&( + "openshell-installation-v1", + &installation.session_id, + &installation.supervisor_instance_id, + installation.connection_epoch, + installation.ownership_epoch, + &installation.pool_route, + &installation.runtime_identity, + &installation.configuration_instance_id, + installation.config_revision, + &installation.service_domain, + &installation.host, + installation.port, + bytes, + )) + .map_err(|_| Status::internal("installation identity encoding failed"))?; + let version = openshell_crypto::sha256(&identity) + .map_err(|_| Status::internal("installation fingerprint failed"))?; + routes.push(DiscoveredServiceRoute { + workspace: workspace.to_string(), + sandbox: sandbox.object_name().to_string(), + name: route.name, + hostname, + endpoint: Some(ServiceRouteEndpoint { + host: installation.host.clone(), + port: installation.port, + }), + installation_version: hex::encode(version), + declaration_revision: route.resource_version, + expires_at: Some( + openshell_core::time::timestamp_from_millis(installation.expires_at_ms) + .map_err(|_| Status::internal("invalid installation expiry"))?, + ), + }); + if routes.len() > MAX_ROUTES { + return Err(Status::resource_exhausted( + "too many discovered service routes", + )); + } + } + } + let after = records(state, workspace).await?; + if before + .iter() + .map(|r| (&r.id, r.resource_version)) + .ne(after.iter().map(|r| (&r.id, r.resource_version))) + { + continue; + } + routes.retain(|route| { + route + .expires_at + .as_ref() + .and_then(|t| openshell_core::time::timestamp_to_millis(t).ok()) + .is_some_and(|t| t > current_time_ms()) + }); + routes.sort_by(|a, b| { + (&a.workspace, &a.sandbox, &a.name).cmp(&(&b.workspace, &b.sandbox, &b.name)) + }); + let mut snapshot = ServiceRouteSnapshot { + routes, + revision: String::new(), + }; + let bytes = snapshot.encode_to_vec(); + if bytes.len() > MAX_BYTES - 128 { + return Err(Status::resource_exhausted( + "service discovery response too large", + )); + } + snapshot.revision = hex::encode( + openshell_crypto::sha256(&bytes) + .map_err(|_| Status::internal("snapshot fingerprint failed"))?, + ); + return Ok(snapshot); + } + Err(Status::unavailable( + "service installations changed during collection; retry snapshot", + )) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::grpc::service_advertisement::{accept, tests::installed_fixture}; + use crate::grpc::test_support::authed_request; + use tokio_stream::StreamExt as _; + + fn request() -> GetServiceRouteSnapshotRequest { + GetServiceRouteSnapshotRequest { + workspace_scope: Some(openshell_core::proto::workspace_selector("default")), + } + } + + #[tokio::test] + async fn snapshot_is_shared_between_gateway_states_and_rejects_expired_or_replaced_owners() { + let (state, owner, report) = installed_fixture().await; + accept(&state, &owner, &report, current_time_ms() + 10_000) + .await + .unwrap(); + let snapshot_a = get_snapshot(&state, authed_request(request())) + .await + .unwrap() + .into_inner() + .snapshot + .unwrap(); + assert_eq!(snapshot_a.routes.len(), 1); + let route = &snapshot_a.routes[0]; + assert_eq!(route.hostname, "default--demo--web.services.example.com"); + assert_eq!(route.endpoint.as_ref().unwrap().port, 9443); + let compute = crate::compute::new_test_runtime(state.store.clone()).await; + let mut replica = ServerState::new( + state.config.clone(), + state.store.clone(), + compute, + crate::sandbox_index::SandboxIndex::new(), + crate::sandbox_watch::SandboxWatchBus::new(), + crate::tracing_bus::TracingLogBus::new(), + Arc::new(crate::supervisor_session::SupervisorSessionRegistry::new()), + None, + ); + replica.admin_role = state.admin_role.clone(); + replica.provider_profile_sources = state.provider_profile_sources.clone(); + let replica = Arc::new(replica); + let snapshot_b = get_snapshot(&replica, authed_request(request())) + .await + .unwrap() + .into_inner() + .snapshot + .unwrap(); + assert_eq!(snapshot_a, snapshot_b); + crate::supervisor_owner::SupervisorOwnerIndex::new( + state.store.clone(), + crate::supervisor_owner::OWNER_TTL, + ) + .publish( + "sandbox", + "replacement", + "instance", + 2, + "other-replica", + "local://other", + ) + .await + .unwrap(); + assert!(snapshot(&state, "default").await.unwrap().routes.is_empty()); + assert!( + snapshot(&replica, "default") + .await + .unwrap() + .routes + .is_empty() + ); + } + + #[tokio::test] + async fn watch_reports_lease_only_renewal_then_withdrawal_and_releases_its_slot() { + let (state, owner, mut report) = installed_fixture().await; + accept(&state, &owner, &report, current_time_ms() + 10_000) + .await + .unwrap(); + let mut stream = watch( + &state, + authed_request(WatchServiceRoutesRequest { + workspace_scope: request().workspace_scope, + }), + ) + .await + .unwrap() + .into_inner(); + let first = stream.next().await.unwrap().unwrap().snapshot.unwrap(); + assert_eq!(state.discovery_watches.available_permits(), 31); + report.lease_sequence = 2; + accept(&state, &owner, &report, current_time_ms() + 14_000) + .await + .unwrap(); + let renewed = tokio::time::timeout(Duration::from_secs(3), stream.next()) + .await + .unwrap() + .unwrap() + .unwrap() + .snapshot + .unwrap(); + assert_ne!(first.revision, renewed.revision); + assert_eq!( + first.routes[0].installation_version, + renewed.routes[0].installation_version + ); + assert_ne!(first.routes[0].expires_at, renewed.routes[0].expires_at); + report.lease_sequence = 3; + report.routes.clear(); + accept(&state, &owner, &report, current_time_ms() + 14_000) + .await + .unwrap(); + let withdrawn = tokio::time::timeout(Duration::from_secs(3), stream.next()) + .await + .unwrap() + .unwrap() + .unwrap() + .snapshot + .unwrap(); + assert!(withdrawn.routes.is_empty()); + drop(stream); + tokio::time::timeout(Duration::from_secs(2), async { + while state.discovery_watches.available_permits() != 32 { + tokio::task::yield_now().await; + } + }) + .await + .unwrap(); + } + + #[tokio::test] + async fn explicit_workspace_and_membership_are_required_and_watch_capacity_is_bounded() { + let (state, _, _) = installed_fixture().await; + assert_eq!( + get_snapshot( + &state, + authed_request(GetServiceRouteSnapshotRequest::default()) + ) + .await + .unwrap_err() + .code(), + tonic::Code::InvalidArgument + ); + assert!( + get_snapshot( + &state, + authed_request(GetServiceRouteSnapshotRequest { + workspace_scope: Some(openshell_core::proto::all_workspaces_selector()) + }) + ) + .await + .is_err() + ); + let mut outsider = authed_request(request()); + if let Some(Principal::User(user)) = outsider.extensions_mut().get_mut::() { + user.identity.roles = vec!["openshell-user".into()]; + user.identity.subject = "outsider".into(); + } + assert_eq!( + get_snapshot(&state, outsider).await.unwrap_err().code(), + tonic::Code::PermissionDenied + ); + let mut anonymous = Request::new(request()); + anonymous.extensions_mut().insert(Principal::Anonymous); + assert_eq!( + get_snapshot(&state, anonymous).await.unwrap_err().code(), + tonic::Code::PermissionDenied + ); + let _all = state + .discovery_watches + .clone() + .acquire_many_owned(32) + .await + .unwrap(); + let error = watch( + &state, + authed_request(WatchServiceRoutesRequest { + workspace_scope: request().workspace_scope, + }), + ) + .await + .expect_err("capacity denied"); + assert_eq!(error.code(), tonic::Code::ResourceExhausted); + } + + #[tokio::test] + async fn watch_terminates_when_workspace_membership_is_revoked() { + use openshell_core::proto::{ObjectMeta, WorkspaceMember, WorkspaceRole}; + let (state, _, _) = installed_fixture().await; + let member = WorkspaceMember { + metadata: Some(ObjectMeta { + id: "discovery-member".into(), + name: "discovery-reader".into(), + workspace: "default".into(), + ..Default::default() + }), + principal_subject: "discovery-reader".into(), + role: WorkspaceRole::User.into(), + }; + state.store.put_message(&member).await.unwrap(); + let mut request = authed_request(WatchServiceRoutesRequest { + workspace_scope: request().workspace_scope, + }); + if let Some(Principal::User(user)) = request.extensions_mut().get_mut::() { + user.identity.roles = vec!["openshell-user".into()]; + user.identity.subject = "discovery-reader".into(); + } + let mut stream = watch(&state, request).await.unwrap().into_inner(); + assert!(stream.next().await.unwrap().is_ok()); + state + .store + .delete("workspace_member", "discovery-member") + .await + .unwrap(); + let error = tokio::time::timeout(Duration::from_secs(3), stream.next()) + .await + .unwrap() + .unwrap() + .unwrap_err(); + assert_eq!(error.code(), tonic::Code::PermissionDenied); + assert!(stream.next().await.is_none()); + assert_eq!(state.discovery_watches.available_permits(), 32); + } + + #[tokio::test] + async fn quiet_watch_ends_at_lifetime_and_releases_capacity() { + let (state, _, _) = installed_fixture().await; + let mut stream = watch( + &state, + authed_request(WatchServiceRoutesRequest { + workspace_scope: request().workspace_scope, + }), + ) + .await + .unwrap() + .into_inner(); + assert!(stream.next().await.unwrap().is_ok()); + tokio::task::yield_now().await; + tokio::time::pause(); + tokio::time::advance(WATCH_LIFETIME).await; + assert!( + tokio::time::timeout(WATCH_LIFETIME + REFRESH_INTERVAL, stream.next()) + .await + .unwrap() + .is_none() + ); + assert_eq!(state.discovery_watches.available_permits(), 32); + } + + #[tokio::test] + async fn collection_overflow_corruption_and_storage_failure_are_errors_not_empty_views() { + let (state, _, _) = installed_fixture().await; + state + .store + .put_if( + OBJECT_TYPE, + "broken", + "broken", + "default", + b"not-json", + None, + crate::persistence::WriteCondition::MustCreate, + ) + .await + .unwrap(); + assert_eq!( + snapshot(&state, "default").await.unwrap_err().code(), + tonic::Code::Internal + ); + state.store.delete(OBJECT_TYPE, "broken").await.unwrap(); + let bytes = vec![b'x'; MAX_BYTES + 1]; + state + .store + .put_if( + OBJECT_TYPE, + "oversized", + "oversized", + "default", + &bytes, + None, + crate::persistence::WriteCondition::MustCreate, + ) + .await + .unwrap(); + assert_eq!( + snapshot(&state, "default").await.unwrap_err().code(), + tonic::Code::ResourceExhausted + ); + state.store.delete(OBJECT_TYPE, "oversized").await.unwrap(); + state.store.close().await; + assert_eq!( + snapshot(&state, "default").await.unwrap_err().code(), + tonic::Code::Unavailable + ); + } +} diff --git a/crates/openshell-server/src/lib.rs b/crates/openshell-server/src/lib.rs index 854e5b4ec9..3720cee880 100644 --- a/crates/openshell-server/src/lib.rs +++ b/crates/openshell-server/src/lib.rs @@ -310,6 +310,8 @@ pub(crate) struct ServerStartupConfig { /// Server state shared across handlers. #[derive(Debug)] pub struct ServerState { + /// Process-local bound on active discovery streams. + pub discovery_watches: Arc, /// Server configuration. pub config: Config, @@ -518,6 +520,7 @@ impl ServerState { service_route_index, gateway_ring: Arc::new(std::sync::RwLock::new(gateway_ring::GatewayRing::default())), gateway_peers: Arc::new(std::sync::RwLock::new(HashMap::new())), + discovery_watches: Arc::new(tokio::sync::Semaphore::new(32)), extension_mint_limiter: auth::extension_mint_limit::ExtensionMintLimiter::default(), middleware_registry: Arc::new(MiddlewareRegistry::default()), oidc_cache, diff --git a/crates/openshell-server/src/storage_proto.rs b/crates/openshell-server/src/storage_proto.rs index b1dd6e9e5e..acc16a918b 100644 --- a/crates/openshell-server/src/storage_proto.rs +++ b/crates/openshell-server/src/storage_proto.rs @@ -164,7 +164,7 @@ mod tests { // SandboxPhase enum. Stored rows never carried those values, so prior // payloads decode unchanged. const PUBLIC_RPC_SCHEMA_SHA256: &str = - "ef8a86dbefbde690c1159c4b2756b4b881513bc3f65e578ee5eb10d0a3f94640"; + "b289c550eee1fe2fcadd6bb5fc59d6625a940af44eca277fbcd9ee256447f2de"; const DURABLE_SCHEMA_SHA256: &str = "ffb20595e36032a9476d1c6956e2dcdc814f85286fc4735751e5ec6f499ea9ed"; const PUBLIC_DURABLE_OVERLAP_SHA256: &str = @@ -631,7 +631,7 @@ mod tests { } assert_eq!( compiled_method_count, - 107 + PROVIDER_READINESS_RPC_SIGNATURES.len() + 109 + PROVIDER_READINESS_RPC_SIGNATURES.len() + PEER_OWNER_RPC_SIGNATURES.len() + PEER_CONFIG_RPC_SIGNATURES.len() + isolation_methods.len() @@ -641,7 +641,7 @@ mod tests { ); assert_eq!( methods.len(), - 80 + PROVIDER_READINESS_RPC_SIGNATURES.len() + 82 + PROVIDER_READINESS_RPC_SIGNATURES.len() + PEER_OWNER_RPC_SIGNATURES.len() + PEER_CONFIG_RPC_SIGNATURES.len(), "inventory every public gateway RPC" @@ -651,7 +651,7 @@ mod tests { .iter() .filter(|method| method.starts_with("openshell.v1.OpenShell/")) .count(), - 80 + PROVIDER_READINESS_RPC_SIGNATURES.len() + 82 + PROVIDER_READINESS_RPC_SIGNATURES.len() + PEER_OWNER_RPC_SIGNATURES.len() + PEER_CONFIG_RPC_SIGNATURES.len() ); @@ -702,7 +702,7 @@ mod tests { overlap_hash.as_str(), ), ( - (333, 31), + (340, 31), (95, 22), (83, 22), PUBLIC_RPC_SCHEMA_SHA256, diff --git a/crates/openshell-server/tests/common/mod.rs b/crates/openshell-server/tests/common/mod.rs index a4072b57b4..7bd5a9925d 100644 --- a/crates/openshell-server/tests/common/mod.rs +++ b/crates/openshell-server/tests/common/mod.rs @@ -53,6 +53,20 @@ pub struct TestOpenShell; #[tonic::async_trait] impl OpenShell for TestOpenShell { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = + ReceiverStream>; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &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 ceb2fa6bf8..f858ebf163 100644 --- a/crates/openshell-server/tests/supervisor_relay_integration.rs +++ b/crates/openshell-server/tests/supervisor_relay_integration.rs @@ -50,6 +50,20 @@ struct RelayGateway { #[tonic::async_trait] impl OpenShell for RelayGateway { + async fn get_service_route_snapshot( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } + type WatchServiceRoutesStream = + ReceiverStream>; + async fn watch_service_routes( + &self, + _: tonic::Request, + ) -> Result, Status> { + Err(Status::unimplemented("unused")) + } async fn peer_notify_config_update( &self, _request: tonic::Request, diff --git a/docs/how-it-works/gateways/configuration.mdx b/docs/how-it-works/gateways/configuration.mdx index c3edf21808..cb120472a6 100644 --- a/docs/how-it-works/gateways/configuration.mdx +++ b/docs/how-it-works/gateways/configuration.mdx @@ -1734,9 +1734,9 @@ Expose services with the existing commands. For direct listener testing, an unnamed service on sandbox `demo` in workspace `default` uses SNI and Host `default--demo.services.example.com`; a service named `web` uses `default--demo--web.services.example.com`. Configure DNS or your ingress to reach -the owning supervisor while preserving that hostname. Automatic discovery and -application URL publication are separate work; current CLI URLs still identify -the existing gateway path. +the owning supervisor while preserving that hostname. The discovery API supplies accepted supervisor endpoints. Application URL +publication is separate work; current CLI URLs still identify the existing +gateway path. Enabled supervisors report installed service routes through their authenticated gateway sessions. The gateway accepts only current configuration and ownership, @@ -1757,3 +1757,12 @@ application streams even if configuration continues renewing. Under a partition, allow for pool membership failure detection before the last serving lease expires. Storage errors prevent lease renewal. Discovery expiry and serving expiry are separate from external ingress readiness. + +Discovery clients can call `GetServiceRouteSnapshot` or `WatchServiceRoutes` with +one explicit workspace selector, `sandbox:read`, and workspace user access. Each +response replaces the workspace route view and includes the hostname, supervisor +TLS endpoint, installation version, and expiry. Preserve the hostname as TLS SNI +and HTTP authority when routing directly to the endpoint. Remove absent routes +and expire cached entries even during discovery errors. An API error does not +mean the workspace has no routes. Watches end after one minute; reconnect and +relist when they end. Discovery-only machine credentials are separate work. diff --git a/proto/openshell.proto b/proto/openshell.proto index 40a55d6728..641059c459 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -251,6 +251,24 @@ service OpenShell { }; } + // Read installed, unexpired application routes in one explicit workspace. + rpc GetServiceRouteSnapshot(GetServiceRouteSnapshotRequest) returns (GetServiceRouteSnapshotResponse) { + option (openshell.options.v1.authorization) = { + auth_mode: "bearer" + scope: "sandbox:read" + workspace_role: "user" + }; + } + + // Full replacement views; reauthorize during the bounded watch lifetime. + rpc WatchServiceRoutes(WatchServiceRoutesRequest) returns (stream WatchServiceRoutesResponse) { + option (openshell.options.v1.authorization) = { + auth_mode: "bearer" + scope: "sandbox:read" + workspace_role: "user" + }; + } + // Delete one sandbox HTTP service endpoint. rpc DeleteService(DeleteServiceRequest) returns (DeleteServiceResponse) { option (openshell.options.v1.authorization) = { @@ -4194,3 +4212,47 @@ message SupervisorServiceAdvertisement { // Domain actually installed by the process listener, not the gateway URL. string service_domain = 5; } + +// One explicit active workspace is required. Omitted and all-workspaces +// selectors are rejected; discovery-only machine grants are separate work. +message GetServiceRouteSnapshotRequest { + openshell.datamodel.v1.WorkspaceSelector workspace_scope = 1; +} +message GetServiceRouteSnapshotResponse { + ServiceRouteSnapshot snapshot = 1; +} +// Same workspace authorization as GetServiceRouteSnapshot. A watch sends an +// initial replacement and later replacements, including lease-only renewal. +// Clients reconnect/relist when the bounded stream ends and expire cached +// routes during discovery errors; errors are not empty replacements. +message WatchServiceRoutesRequest { + openshell.datamodel.v1.WorkspaceSelector workspace_scope = 1; +} +message WatchServiceRoutesResponse { + ServiceRouteSnapshot snapshot = 1; +} +message ServiceRouteSnapshot { + repeated DiscoveredServiceRoute routes = 1; + // Opaque equality token for this complete view, including lease expiries. + // No ordering across replicas or server restarts is implied. + string revision = 2; +} +// Trusted supervisor TLS endpoint. Preserve DiscoveredServiceRoute.hostname +// as SNI and HTTP authority; this endpoint never addresses a workload port. +message ServiceRouteEndpoint { + string host = 1; + uint32 port = 2; +} +// Accepted installation evidence, not application health or ingress readiness. +message DiscoveredServiceRoute { + string workspace = 1; + string sandbox = 2; + // Canonical service name; empty identifies the existing unnamed service. + string name = 3; + string hostname = 4; + ServiceRouteEndpoint endpoint = 5; + // Changes on owner/backend/declaration replacement, but not lease renewal. + string installation_version = 6; + uint64 declaration_revision = 7; + google.protobuf.Timestamp expires_at = 8; +} diff --git a/sdk/go/proto/openshellv1/openshell.pb.go b/sdk/go/proto/openshellv1/openshell.pb.go index b30c227dde..c4a17cad65 100644 --- a/sdk/go/proto/openshellv1/openshell.pb.go +++ b/sdk/go/proto/openshellv1/openshell.pb.go @@ -19714,6 +19714,399 @@ func (x *SupervisorServiceAdvertisement) GetServiceDomain() string { return "" } +// One explicit active workspace is required. Omitted and all-workspaces +// selectors are rejected; discovery-only machine grants are separate work. +type GetServiceRouteSnapshotRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + WorkspaceScope *datamodelv1.WorkspaceSelector `protobuf:"bytes,1,opt,name=workspace_scope,json=workspaceScope,proto3" json:"workspace_scope,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetServiceRouteSnapshotRequest) Reset() { + *x = GetServiceRouteSnapshotRequest{} + mi := &file_openshell_proto_msgTypes[253] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetServiceRouteSnapshotRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetServiceRouteSnapshotRequest) ProtoMessage() {} + +func (x *GetServiceRouteSnapshotRequest) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[253] + 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 GetServiceRouteSnapshotRequest.ProtoReflect.Descriptor instead. +func (*GetServiceRouteSnapshotRequest) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{253} +} + +func (x *GetServiceRouteSnapshotRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { + if x != nil { + return x.WorkspaceScope + } + return nil +} + +type GetServiceRouteSnapshotResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Snapshot *ServiceRouteSnapshot `protobuf:"bytes,1,opt,name=snapshot,proto3" json:"snapshot,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetServiceRouteSnapshotResponse) Reset() { + *x = GetServiceRouteSnapshotResponse{} + mi := &file_openshell_proto_msgTypes[254] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetServiceRouteSnapshotResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetServiceRouteSnapshotResponse) ProtoMessage() {} + +func (x *GetServiceRouteSnapshotResponse) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[254] + 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 GetServiceRouteSnapshotResponse.ProtoReflect.Descriptor instead. +func (*GetServiceRouteSnapshotResponse) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{254} +} + +func (x *GetServiceRouteSnapshotResponse) GetSnapshot() *ServiceRouteSnapshot { + if x != nil { + return x.Snapshot + } + return nil +} + +// Same workspace authorization as GetServiceRouteSnapshot. A watch sends an +// initial replacement and later replacements, including lease-only renewal. +// Clients reconnect/relist when the bounded stream ends and expire cached +// routes during discovery errors; errors are not empty replacements. +type WatchServiceRoutesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + WorkspaceScope *datamodelv1.WorkspaceSelector `protobuf:"bytes,1,opt,name=workspace_scope,json=workspaceScope,proto3" json:"workspace_scope,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchServiceRoutesRequest) Reset() { + *x = WatchServiceRoutesRequest{} + mi := &file_openshell_proto_msgTypes[255] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchServiceRoutesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchServiceRoutesRequest) ProtoMessage() {} + +func (x *WatchServiceRoutesRequest) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[255] + 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 WatchServiceRoutesRequest.ProtoReflect.Descriptor instead. +func (*WatchServiceRoutesRequest) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{255} +} + +func (x *WatchServiceRoutesRequest) GetWorkspaceScope() *datamodelv1.WorkspaceSelector { + if x != nil { + return x.WorkspaceScope + } + return nil +} + +type WatchServiceRoutesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Snapshot *ServiceRouteSnapshot `protobuf:"bytes,1,opt,name=snapshot,proto3" json:"snapshot,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WatchServiceRoutesResponse) Reset() { + *x = WatchServiceRoutesResponse{} + mi := &file_openshell_proto_msgTypes[256] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WatchServiceRoutesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchServiceRoutesResponse) ProtoMessage() {} + +func (x *WatchServiceRoutesResponse) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[256] + 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 WatchServiceRoutesResponse.ProtoReflect.Descriptor instead. +func (*WatchServiceRoutesResponse) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{256} +} + +func (x *WatchServiceRoutesResponse) GetSnapshot() *ServiceRouteSnapshot { + if x != nil { + return x.Snapshot + } + return nil +} + +type ServiceRouteSnapshot struct { + state protoimpl.MessageState `protogen:"open.v1"` + Routes []*DiscoveredServiceRoute `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes,omitempty"` + // Opaque equality token for this complete view, including lease expiries. + // No ordering across replicas or server restarts is implied. + Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServiceRouteSnapshot) Reset() { + *x = ServiceRouteSnapshot{} + mi := &file_openshell_proto_msgTypes[257] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceRouteSnapshot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceRouteSnapshot) ProtoMessage() {} + +func (x *ServiceRouteSnapshot) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[257] + 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 ServiceRouteSnapshot.ProtoReflect.Descriptor instead. +func (*ServiceRouteSnapshot) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{257} +} + +func (x *ServiceRouteSnapshot) GetRoutes() []*DiscoveredServiceRoute { + if x != nil { + return x.Routes + } + return nil +} + +func (x *ServiceRouteSnapshot) GetRevision() string { + if x != nil { + return x.Revision + } + return "" +} + +// Trusted supervisor TLS endpoint. Preserve DiscoveredServiceRoute.hostname +// as SNI and HTTP authority; this endpoint never addresses a workload port. +type ServiceRouteEndpoint struct { + state protoimpl.MessageState `protogen:"open.v1"` + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ServiceRouteEndpoint) Reset() { + *x = ServiceRouteEndpoint{} + mi := &file_openshell_proto_msgTypes[258] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServiceRouteEndpoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceRouteEndpoint) ProtoMessage() {} + +func (x *ServiceRouteEndpoint) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[258] + 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 ServiceRouteEndpoint.ProtoReflect.Descriptor instead. +func (*ServiceRouteEndpoint) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{258} +} + +func (x *ServiceRouteEndpoint) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *ServiceRouteEndpoint) GetPort() uint32 { + if x != nil { + return x.Port + } + return 0 +} + +// Accepted installation evidence, not application health or ingress readiness. +type DiscoveredServiceRoute struct { + state protoimpl.MessageState `protogen:"open.v1"` + Workspace string `protobuf:"bytes,1,opt,name=workspace,proto3" json:"workspace,omitempty"` + Sandbox string `protobuf:"bytes,2,opt,name=sandbox,proto3" json:"sandbox,omitempty"` + // Canonical service name; empty identifies the existing unnamed service. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Hostname string `protobuf:"bytes,4,opt,name=hostname,proto3" json:"hostname,omitempty"` + Endpoint *ServiceRouteEndpoint `protobuf:"bytes,5,opt,name=endpoint,proto3" json:"endpoint,omitempty"` + // Changes on owner/backend/declaration replacement, but not lease renewal. + InstallationVersion string `protobuf:"bytes,6,opt,name=installation_version,json=installationVersion,proto3" json:"installation_version,omitempty"` + DeclarationRevision uint64 `protobuf:"varint,7,opt,name=declaration_revision,json=declarationRevision,proto3" json:"declaration_revision,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DiscoveredServiceRoute) Reset() { + *x = DiscoveredServiceRoute{} + mi := &file_openshell_proto_msgTypes[259] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DiscoveredServiceRoute) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiscoveredServiceRoute) ProtoMessage() {} + +func (x *DiscoveredServiceRoute) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[259] + 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 DiscoveredServiceRoute.ProtoReflect.Descriptor instead. +func (*DiscoveredServiceRoute) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{259} +} + +func (x *DiscoveredServiceRoute) GetWorkspace() string { + if x != nil { + return x.Workspace + } + return "" +} + +func (x *DiscoveredServiceRoute) GetSandbox() string { + if x != nil { + return x.Sandbox + } + return "" +} + +func (x *DiscoveredServiceRoute) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DiscoveredServiceRoute) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *DiscoveredServiceRoute) GetEndpoint() *ServiceRouteEndpoint { + if x != nil { + return x.Endpoint + } + return nil +} + +func (x *DiscoveredServiceRoute) GetInstallationVersion() string { + if x != nil { + return x.InstallationVersion + } + return "" +} + +func (x *DiscoveredServiceRoute) GetDeclarationRevision() uint64 { + if x != nil { + return x.DeclarationRevision + } + return 0 +} + +func (x *DiscoveredServiceRoute) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + var File_openshell_proto protoreflect.FileDescriptor const file_openshell_proto_rawDesc = "" + @@ -21189,7 +21582,31 @@ const file_openshell_proto_rawDesc = "" + "\x19configuration_instance_id\x18\x02 \x01(\tR\x17configurationInstanceId\x12'\n" + "\x0fconfig_revision\x18\x03 \x01(\x04R\x0econfigRevision\x12A\n" + "\x06routes\x18\x04 \x03(\v2).openshell.sandbox.v1.SandboxServiceRouteR\x06routes\x12%\n" + - "\x0eservice_domain\x18\x05 \x01(\tR\rserviceDomain*\xca\x01\n" + + "\x0eservice_domain\x18\x05 \x01(\tR\rserviceDomain\"t\n" + + "\x1eGetServiceRouteSnapshotRequest\x12R\n" + + "\x0fworkspace_scope\x18\x01 \x01(\v2).openshell.datamodel.v1.WorkspaceSelectorR\x0eworkspaceScope\"a\n" + + "\x1fGetServiceRouteSnapshotResponse\x12>\n" + + "\bsnapshot\x18\x01 \x01(\v2\".openshell.v1.ServiceRouteSnapshotR\bsnapshot\"o\n" + + "\x19WatchServiceRoutesRequest\x12R\n" + + "\x0fworkspace_scope\x18\x01 \x01(\v2).openshell.datamodel.v1.WorkspaceSelectorR\x0eworkspaceScope\"\\\n" + + "\x1aWatchServiceRoutesResponse\x12>\n" + + "\bsnapshot\x18\x01 \x01(\v2\".openshell.v1.ServiceRouteSnapshotR\bsnapshot\"p\n" + + "\x14ServiceRouteSnapshot\x12<\n" + + "\x06routes\x18\x01 \x03(\v2$.openshell.v1.DiscoveredServiceRouteR\x06routes\x12\x1a\n" + + "\brevision\x18\x02 \x01(\tR\brevision\">\n" + + "\x14ServiceRouteEndpoint\x12\x12\n" + + "\x04host\x18\x01 \x01(\tR\x04host\x12\x12\n" + + "\x04port\x18\x02 \x01(\rR\x04port\"\xe1\x02\n" + + "\x16DiscoveredServiceRoute\x12\x1c\n" + + "\tworkspace\x18\x01 \x01(\tR\tworkspace\x12\x18\n" + + "\asandbox\x18\x02 \x01(\tR\asandbox\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x12\x1a\n" + + "\bhostname\x18\x04 \x01(\tR\bhostname\x12>\n" + + "\bendpoint\x18\x05 \x01(\v2\".openshell.v1.ServiceRouteEndpointR\bendpoint\x121\n" + + "\x14installation_version\x18\x06 \x01(\tR\x13installationVersion\x121\n" + + "\x14declaration_revision\x18\a \x01(\x04R\x13declarationRevision\x129\n" + + "\n" + + "expires_at\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt*\xca\x01\n" + "\rExtensionKind\x12\x1e\n" + "\x1aEXTENSION_KIND_UNSPECIFIED\x10\x00\x12!\n" + "\x1dEXTENSION_KIND_COMPUTE_DRIVER\x10\x01\x12$\n" + @@ -21342,7 +21759,7 @@ const file_openshell_proto_rawDesc = "" + "-SERVICE_AUTHORIZATION_MODE_BEARER_PASSTHROUGH\x10\x02*i\n" + "\x15EndpointFailureDomain\x12'\n" + "#ENDPOINT_FAILURE_DOMAIN_UNSPECIFIED\x10\x00\x12'\n" + - "#ENDPOINT_FAILURE_DOMAIN_TOKEN_GRANT\x10\x012\xa6Y\n" + + "#ENDPOINT_FAILURE_DOMAIN_TOKEN_GRANT\x10\x012\xcf[\n" + "\tOpenShell\x12Z\n" + "\x06Health\x12\x1b.openshell.v1.HealthRequest\x1a\x1c.openshell.v1.HealthResponse\"\x15\x82\xb5\x18\x11\n" + "\x0funauthenticated\x12i\n" + @@ -21393,7 +21810,11 @@ const file_openshell_proto_rawDesc = "" + "GetService\x12\x1f.openshell.v1.GetServiceRequest\x1a%.openshell.v1.ServiceEndpointResponse\" \x82\xb5\x18\x1c\n" + "\x06bearer\x12\x04user\"\fsandbox:read\x12w\n" + "\fListServices\x12!.openshell.v1.ListServicesRequest\x1a\".openshell.v1.ListServicesResponse\" \x82\xb5\x18\x1c\n" + - "\x06bearer\x12\x04user\"\fsandbox:read\x12{\n" + + "\x06bearer\x12\x04user\"\fsandbox:read\x12\x98\x01\n" + + "\x17GetServiceRouteSnapshot\x12,.openshell.v1.GetServiceRouteSnapshotRequest\x1a-.openshell.v1.GetServiceRouteSnapshotResponse\" \x82\xb5\x18\x1c\n" + + "\x06bearer\x12\x04user\"\fsandbox:read\x12\x8b\x01\n" + + "\x12WatchServiceRoutes\x12'.openshell.v1.WatchServiceRoutesRequest\x1a(.openshell.v1.WatchServiceRoutesResponse\" \x82\xb5\x18\x1c\n" + + "\x06bearer\x12\x04user\"\fsandbox:read0\x01\x12{\n" + "\rDeleteService\x12\".openshell.v1.DeleteServiceRequest\x1a#.openshell.v1.DeleteServiceResponse\"!\x82\xb5\x18\x1d\n" + "\x06bearer\x12\x04user\"\rsandbox:write\x12\x84\x01\n" + "\x10RevokeSshSession\x12%.openshell.v1.RevokeSshSessionRequest\x1a&.openshell.v1.RevokeSshSessionResponse\"!\x82\xb5\x18\x1d\n" + @@ -21539,7 +21960,7 @@ func file_openshell_proto_rawDescGZIP() []byte { } var file_openshell_proto_enumTypes = make([]protoimpl.EnumInfo, 22) -var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 279) +var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 286) var file_openshell_proto_goTypes = []any{ (ExtensionKind)(0), // 0: openshell.v1.ExtensionKind (SandboxPhase)(0), // 1: openshell.v1.SandboxPhase @@ -21816,59 +22237,66 @@ var file_openshell_proto_goTypes = []any{ (*EndpointFailure)(nil), // 272: openshell.v1.EndpointFailure (*ServiceRouteLease)(nil), // 273: openshell.v1.ServiceRouteLease (*SupervisorServiceAdvertisement)(nil), // 274: openshell.v1.SupervisorServiceAdvertisement - nil, // 275: openshell.v1.SandboxSpec.EnvironmentEntry - nil, // 276: openshell.v1.SandboxTemplate.LabelsEntry - nil, // 277: openshell.v1.SandboxTemplate.AnnotationsEntry - nil, // 278: openshell.v1.SandboxTemplate.EnvironmentEntry - nil, // 279: openshell.v1.SandboxWorkloadConfig.EnvironmentEntry - nil, // 280: openshell.v1.PlatformEvent.MetadataEntry - nil, // 281: openshell.v1.CreateSandboxRequest.LabelsEntry - nil, // 282: openshell.v1.CreateSandboxRequest.AnnotationsEntry - nil, // 283: openshell.v1.SandboxResponse.ServiceUrlsEntry - nil, // 284: openshell.v1.ExecSandboxRequest.EnvironmentEntry - nil, // 285: openshell.v1.SandboxLogLine.FieldsEntry - nil, // 286: openshell.v1.GetProviderCredentialsResponse.CredentialsEntry - nil, // 287: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry - nil, // 288: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - nil, // 289: openshell.v1.ProviderProfile.AnnotationsEntry - nil, // 290: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - nil, // 291: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry - nil, // 292: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - nil, // 293: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry - nil, // 294: openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry - nil, // 295: openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry - nil, // 296: openshell.v1.ProviderEnvironmentSnapshot.FilesEntry - nil, // 297: openshell.v1.UpdateConfigRequest.AnnotationsEntry - nil, // 298: openshell.v1.UpdateConfigResponse.AnnotationsEntry - nil, // 299: openshell.v1.SandboxPolicyRevision.ProvenanceEntry - nil, // 300: openshell.v1.CreateWorkspaceRequest.LabelsEntry - (*timestamppb.Timestamp)(nil), // 301: google.protobuf.Timestamp - (*datamodelv1.ObjectMeta)(nil), // 302: openshell.datamodel.v1.ObjectMeta - (*sandboxv1.SandboxPolicy)(nil), // 303: openshell.sandbox.v1.SandboxPolicy - (*structpb.Struct)(nil), // 304: google.protobuf.Struct - (*durationpb.Duration)(nil), // 305: google.protobuf.Duration - (*datamodelv1.WorkspaceSelector)(nil), // 306: openshell.datamodel.v1.WorkspaceSelector - (*datamodelv1.Provider)(nil), // 307: openshell.datamodel.v1.Provider - (sandboxv1.PolicySource)(0), // 308: openshell.sandbox.v1.PolicySource - (*sandboxv1.NetworkEndpoint)(nil), // 309: openshell.sandbox.v1.NetworkEndpoint - (*sandboxv1.NetworkBinary)(nil), // 310: openshell.sandbox.v1.NetworkBinary - (*sandboxv1.SettingValue)(nil), // 311: openshell.sandbox.v1.SettingValue - (*sandboxv1.NetworkPolicyRule)(nil), // 312: openshell.sandbox.v1.NetworkPolicyRule - (*sandboxv1.L7DenyRule)(nil), // 313: openshell.sandbox.v1.L7DenyRule - (*sandboxv1.L7Rule)(nil), // 314: openshell.sandbox.v1.L7Rule - (*sandboxv1.SandboxConfigSnapshot)(nil), // 315: openshell.sandbox.v1.SandboxConfigSnapshot - (*datamodelv1.Workspace)(nil), // 316: openshell.datamodel.v1.Workspace - (*sandboxv1.SandboxServiceRoute)(nil), // 317: openshell.sandbox.v1.SandboxServiceRoute - (*sandboxv1.GetSandboxConfigRequest)(nil), // 318: openshell.sandbox.v1.GetSandboxConfigRequest - (*sandboxv1.GetGatewayConfigRequest)(nil), // 319: openshell.sandbox.v1.GetGatewayConfigRequest - (*sandboxv1.GetSandboxConfigResponse)(nil), // 320: openshell.sandbox.v1.GetSandboxConfigResponse - (*sandboxv1.GetGatewayConfigResponse)(nil), // 321: openshell.sandbox.v1.GetGatewayConfigResponse + (*GetServiceRouteSnapshotRequest)(nil), // 275: openshell.v1.GetServiceRouteSnapshotRequest + (*GetServiceRouteSnapshotResponse)(nil), // 276: openshell.v1.GetServiceRouteSnapshotResponse + (*WatchServiceRoutesRequest)(nil), // 277: openshell.v1.WatchServiceRoutesRequest + (*WatchServiceRoutesResponse)(nil), // 278: openshell.v1.WatchServiceRoutesResponse + (*ServiceRouteSnapshot)(nil), // 279: openshell.v1.ServiceRouteSnapshot + (*ServiceRouteEndpoint)(nil), // 280: openshell.v1.ServiceRouteEndpoint + (*DiscoveredServiceRoute)(nil), // 281: openshell.v1.DiscoveredServiceRoute + nil, // 282: openshell.v1.SandboxSpec.EnvironmentEntry + nil, // 283: openshell.v1.SandboxTemplate.LabelsEntry + nil, // 284: openshell.v1.SandboxTemplate.AnnotationsEntry + nil, // 285: openshell.v1.SandboxTemplate.EnvironmentEntry + nil, // 286: openshell.v1.SandboxWorkloadConfig.EnvironmentEntry + nil, // 287: openshell.v1.PlatformEvent.MetadataEntry + nil, // 288: openshell.v1.CreateSandboxRequest.LabelsEntry + nil, // 289: openshell.v1.CreateSandboxRequest.AnnotationsEntry + nil, // 290: openshell.v1.SandboxResponse.ServiceUrlsEntry + nil, // 291: openshell.v1.ExecSandboxRequest.EnvironmentEntry + nil, // 292: openshell.v1.SandboxLogLine.FieldsEntry + nil, // 293: openshell.v1.GetProviderCredentialsResponse.CredentialsEntry + nil, // 294: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry + nil, // 295: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + nil, // 296: openshell.v1.ProviderProfile.AnnotationsEntry + nil, // 297: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + nil, // 298: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry + nil, // 299: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + nil, // 300: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + nil, // 301: openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry + nil, // 302: openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry + nil, // 303: openshell.v1.ProviderEnvironmentSnapshot.FilesEntry + nil, // 304: openshell.v1.UpdateConfigRequest.AnnotationsEntry + nil, // 305: openshell.v1.UpdateConfigResponse.AnnotationsEntry + nil, // 306: openshell.v1.SandboxPolicyRevision.ProvenanceEntry + nil, // 307: openshell.v1.CreateWorkspaceRequest.LabelsEntry + (*timestamppb.Timestamp)(nil), // 308: google.protobuf.Timestamp + (*datamodelv1.ObjectMeta)(nil), // 309: openshell.datamodel.v1.ObjectMeta + (*sandboxv1.SandboxPolicy)(nil), // 310: openshell.sandbox.v1.SandboxPolicy + (*structpb.Struct)(nil), // 311: google.protobuf.Struct + (*durationpb.Duration)(nil), // 312: google.protobuf.Duration + (*datamodelv1.WorkspaceSelector)(nil), // 313: openshell.datamodel.v1.WorkspaceSelector + (*datamodelv1.Provider)(nil), // 314: openshell.datamodel.v1.Provider + (sandboxv1.PolicySource)(0), // 315: openshell.sandbox.v1.PolicySource + (*sandboxv1.NetworkEndpoint)(nil), // 316: openshell.sandbox.v1.NetworkEndpoint + (*sandboxv1.NetworkBinary)(nil), // 317: openshell.sandbox.v1.NetworkBinary + (*sandboxv1.SettingValue)(nil), // 318: openshell.sandbox.v1.SettingValue + (*sandboxv1.NetworkPolicyRule)(nil), // 319: openshell.sandbox.v1.NetworkPolicyRule + (*sandboxv1.L7DenyRule)(nil), // 320: openshell.sandbox.v1.L7DenyRule + (*sandboxv1.L7Rule)(nil), // 321: openshell.sandbox.v1.L7Rule + (*sandboxv1.SandboxConfigSnapshot)(nil), // 322: openshell.sandbox.v1.SandboxConfigSnapshot + (*datamodelv1.Workspace)(nil), // 323: openshell.datamodel.v1.Workspace + (*sandboxv1.SandboxServiceRoute)(nil), // 324: openshell.sandbox.v1.SandboxServiceRoute + (*sandboxv1.GetSandboxConfigRequest)(nil), // 325: openshell.sandbox.v1.GetSandboxConfigRequest + (*sandboxv1.GetGatewayConfigRequest)(nil), // 326: openshell.sandbox.v1.GetGatewayConfigRequest + (*sandboxv1.GetSandboxConfigResponse)(nil), // 327: openshell.sandbox.v1.GetSandboxConfigResponse + (*sandboxv1.GetGatewayConfigResponse)(nil), // 328: openshell.sandbox.v1.GetGatewayConfigResponse } var file_openshell_proto_depIdxs = []int32{ - 301, // 0: openshell.v1.IssueSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp - 301, // 1: openshell.v1.RefreshSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp + 308, // 0: openshell.v1.IssueSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp + 308, // 1: openshell.v1.RefreshSandboxTokenResponse.expiration_time:type_name -> google.protobuf.Timestamp 263, // 2: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential - 301, // 3: openshell.v1.RefreshSandboxTokenResponse.sandbox_expiration_time:type_name -> google.protobuf.Timestamp + 308, // 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 33, // 6: openshell.v1.GetGatewayInfoResponse.compute_drivers:type_name -> openshell.v1.ComputeDriverInfo @@ -21879,118 +22307,118 @@ var file_openshell_proto_depIdxs = []int32{ 36, // 11: openshell.v1.ResourceCapabilities.cpu:type_name -> openshell.v1.CpuResourceCapabilities 37, // 12: openshell.v1.ResourceCapabilities.memory:type_name -> openshell.v1.MemoryResourceCapabilities 38, // 13: openshell.v1.ResourceCapabilities.gpu:type_name -> openshell.v1.GpuResourceCapabilities - 302, // 14: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 309, // 14: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 40, // 15: openshell.v1.Sandbox.spec:type_name -> openshell.v1.SandboxSpec 51, // 16: openshell.v1.Sandbox.status:type_name -> openshell.v1.SandboxStatus 50, // 17: openshell.v1.Sandbox.created_from_workload_template:type_name -> openshell.v1.SandboxWorkloadTemplateProvenance - 275, // 18: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry + 282, // 18: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry 43, // 19: openshell.v1.SandboxSpec.template:type_name -> openshell.v1.SandboxTemplate - 303, // 20: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 310, // 20: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy 41, // 21: openshell.v1.SandboxSpec.resource_requirements:type_name -> openshell.v1.ResourceRequirements 17, // 22: openshell.v1.SandboxSpec.restart_policy:type_name -> openshell.v1.SandboxRestartPolicy 42, // 23: openshell.v1.ResourceRequirements.gpu:type_name -> openshell.v1.GpuResourceRequirements - 276, // 24: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry - 277, // 25: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry - 278, // 26: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry - 304, // 27: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct - 304, // 28: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct - 302, // 29: openshell.v1.SandboxWorkloadTemplate.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 283, // 24: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry + 284, // 25: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry + 285, // 26: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry + 311, // 27: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct + 311, // 28: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct + 309, // 29: openshell.v1.SandboxWorkloadTemplate.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 45, // 30: openshell.v1.SandboxWorkloadTemplate.spec:type_name -> openshell.v1.SandboxWorkloadTemplateSpec 46, // 31: openshell.v1.SandboxWorkloadTemplateSpec.workload:type_name -> openshell.v1.SandboxWorkloadConfig - 304, // 32: openshell.v1.SandboxWorkloadTemplateSpec.driver_config:type_name -> google.protobuf.Struct + 311, // 32: openshell.v1.SandboxWorkloadTemplateSpec.driver_config:type_name -> google.protobuf.Struct 48, // 33: openshell.v1.SandboxWorkloadTemplateSpec.desired_service_level:type_name -> openshell.v1.SandboxServiceLevel - 279, // 34: openshell.v1.SandboxWorkloadConfig.environment:type_name -> openshell.v1.SandboxWorkloadConfig.EnvironmentEntry + 286, // 34: openshell.v1.SandboxWorkloadConfig.environment:type_name -> openshell.v1.SandboxWorkloadConfig.EnvironmentEntry 47, // 35: openshell.v1.SandboxWorkloadConfig.resources:type_name -> openshell.v1.SandboxResources 42, // 36: openshell.v1.SandboxResources.gpu:type_name -> openshell.v1.GpuResourceRequirements 49, // 37: openshell.v1.SandboxServiceLevel.startup:type_name -> openshell.v1.SandboxStartup - 305, // 38: openshell.v1.SandboxStartup.ready_within:type_name -> google.protobuf.Duration + 312, // 38: openshell.v1.SandboxStartup.ready_within:type_name -> google.protobuf.Duration 52, // 39: openshell.v1.SandboxStatus.conditions:type_name -> openshell.v1.SandboxCondition 1, // 40: openshell.v1.SandboxStatus.phase:type_name -> openshell.v1.SandboxPhase 269, // 41: openshell.v1.SandboxStatus.endpoint_statuses:type_name -> openshell.v1.EndpointStatus 185, // 42: openshell.v1.SandboxStatus.configuration_admission:type_name -> openshell.v1.SandboxConfigurationAdmission 270, // 43: openshell.v1.SandboxStatus.provisioning:type_name -> openshell.v1.SandboxProvisioning - 301, // 44: openshell.v1.SandboxStatus.next_restart_time:type_name -> google.protobuf.Timestamp - 301, // 45: openshell.v1.SandboxStatus.main_process_started_time:type_name -> google.protobuf.Timestamp + 308, // 44: openshell.v1.SandboxStatus.next_restart_time:type_name -> google.protobuf.Timestamp + 308, // 45: openshell.v1.SandboxStatus.main_process_started_time:type_name -> google.protobuf.Timestamp 267, // 46: openshell.v1.SandboxStatus.last_token_grant_failure:type_name -> openshell.v1.TokenGrantFailureObservation - 301, // 47: openshell.v1.SandboxCondition.transition_time:type_name -> google.protobuf.Timestamp - 301, // 48: openshell.v1.PlatformEvent.event_time:type_name -> google.protobuf.Timestamp - 280, // 49: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry - 306, // 50: openshell.v1.CreateSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 47: openshell.v1.SandboxCondition.transition_time:type_name -> google.protobuf.Timestamp + 308, // 48: openshell.v1.PlatformEvent.event_time:type_name -> google.protobuf.Timestamp + 287, // 49: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry + 313, // 50: openshell.v1.CreateSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 40, // 51: openshell.v1.CreateSandboxRequest.spec:type_name -> openshell.v1.SandboxSpec - 281, // 52: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry - 282, // 53: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry + 288, // 52: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry + 289, // 53: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry 271, // 54: openshell.v1.CreateSandboxRequest.service_exposures:type_name -> openshell.v1.SandboxServiceExposure - 306, // 55: openshell.v1.CreateSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 55: openshell.v1.CreateSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 44, // 56: openshell.v1.CreateSandboxTemplateRequest.template:type_name -> openshell.v1.SandboxWorkloadTemplate - 306, // 57: openshell.v1.GetSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 58: openshell.v1.ListSandboxTemplatesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 59: openshell.v1.DeleteSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 57: openshell.v1.GetSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 58: openshell.v1.ListSandboxTemplatesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 59: openshell.v1.DeleteSandboxTemplateRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 44, // 60: openshell.v1.SandboxTemplateResponse.template:type_name -> openshell.v1.SandboxWorkloadTemplate 44, // 61: openshell.v1.ListSandboxTemplatesResponse.templates:type_name -> openshell.v1.SandboxWorkloadTemplate 18, // 62: openshell.v1.DeleteSandboxTemplateResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 306, // 63: openshell.v1.BeginRootfsTarStagingRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 301, // 64: openshell.v1.BeginRootfsTarStagingResponse.expiration_time:type_name -> google.protobuf.Timestamp - 306, // 65: openshell.v1.GetSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 66: openshell.v1.ListSandboxesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 67: openshell.v1.ListSandboxProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 68: openshell.v1.AttachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 69: openshell.v1.DetachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 70: openshell.v1.DeleteSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 71: openshell.v1.StopSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 72: openshell.v1.StartSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 73: openshell.v1.SuspendSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 74: openshell.v1.ResumeSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 63: openshell.v1.BeginRootfsTarStagingRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 64: openshell.v1.BeginRootfsTarStagingResponse.expiration_time:type_name -> google.protobuf.Timestamp + 313, // 65: openshell.v1.GetSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 66: openshell.v1.ListSandboxesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 67: openshell.v1.ListSandboxProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 68: openshell.v1.AttachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 69: openshell.v1.DetachSandboxProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 70: openshell.v1.DeleteSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 71: openshell.v1.StopSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 72: openshell.v1.StartSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 73: openshell.v1.SuspendSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 74: openshell.v1.ResumeSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 39, // 75: openshell.v1.SandboxResponse.sandbox:type_name -> openshell.v1.Sandbox - 283, // 76: openshell.v1.SandboxResponse.service_urls:type_name -> openshell.v1.SandboxResponse.ServiceUrlsEntry + 290, // 76: openshell.v1.SandboxResponse.service_urls:type_name -> openshell.v1.SandboxResponse.ServiceUrlsEntry 39, // 77: openshell.v1.ListSandboxesResponse.sandboxes:type_name -> openshell.v1.Sandbox - 307, // 78: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 314, // 78: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider 39, // 79: openshell.v1.AttachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox 83, // 80: openshell.v1.AttachSandboxProviderResponse.receipt:type_name -> openshell.v1.ProviderMutationReceipt 39, // 81: openshell.v1.DetachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox 83, // 82: openshell.v1.DetachSandboxProviderResponse.receipt:type_name -> openshell.v1.ProviderMutationReceipt 81, // 83: openshell.v1.ConfigSnapshotRevision.sandbox_config:type_name -> openshell.v1.SandboxConfigRevision 79, // 84: openshell.v1.ConfigSnapshotRevision.provider_target:type_name -> openshell.v1.ProviderDesiredIdentity - 308, // 85: openshell.v1.SandboxConfigRevision.policy_source:type_name -> openshell.sandbox.v1.PolicySource + 315, // 85: openshell.v1.SandboxConfigRevision.policy_source:type_name -> openshell.sandbox.v1.PolicySource 5, // 86: openshell.v1.ConfigUpdateOperation.component:type_name -> openshell.v1.ConfigComponent 80, // 87: openshell.v1.ConfigUpdateOperation.target_revision:type_name -> openshell.v1.ConfigSnapshotRevision 7, // 88: openshell.v1.ConfigUpdateOperation.state:type_name -> openshell.v1.ConfigUpdateOperationState 6, // 89: openshell.v1.ConfigUpdateOperation.outcome:type_name -> openshell.v1.ConfigApplyOutcome - 301, // 90: openshell.v1.ConfigUpdateOperation.created_time:type_name -> google.protobuf.Timestamp - 301, // 91: openshell.v1.ConfigUpdateOperation.updated_time:type_name -> google.protobuf.Timestamp - 301, // 92: openshell.v1.ConfigUpdateOperation.completed_time:type_name -> google.protobuf.Timestamp + 308, // 90: openshell.v1.ConfigUpdateOperation.created_time:type_name -> google.protobuf.Timestamp + 308, // 91: openshell.v1.ConfigUpdateOperation.updated_time:type_name -> google.protobuf.Timestamp + 308, // 92: openshell.v1.ConfigUpdateOperation.completed_time:type_name -> google.protobuf.Timestamp 2, // 93: openshell.v1.ProviderMutationReceipt.kind:type_name -> openshell.v1.ProviderMutationKind 79, // 94: openshell.v1.ProviderMutationReceipt.desired:type_name -> openshell.v1.ProviderDesiredIdentity - 301, // 95: openshell.v1.ProviderMutationReceipt.persisted_time:type_name -> google.protobuf.Timestamp + 308, // 95: openshell.v1.ProviderMutationReceipt.persisted_time:type_name -> google.protobuf.Timestamp 4, // 96: openshell.v1.ProviderReadinessObservation.reason:type_name -> openshell.v1.ProviderReadinessReason 83, // 97: openshell.v1.ProviderReadinessStatus.receipt:type_name -> openshell.v1.ProviderMutationReceipt 3, // 98: openshell.v1.ProviderReadinessStatus.state:type_name -> openshell.v1.ProviderReadinessState 4, // 99: openshell.v1.ProviderReadinessStatus.reason:type_name -> openshell.v1.ProviderReadinessReason 84, // 100: openshell.v1.ProviderReadinessStatus.observed:type_name -> openshell.v1.ProviderReadinessObservation - 301, // 101: openshell.v1.ProviderReadinessStatus.observed_time:type_name -> google.protobuf.Timestamp - 301, // 102: openshell.v1.ProviderReadinessStatus.evaluated_time:type_name -> google.protobuf.Timestamp + 308, // 101: openshell.v1.ProviderReadinessStatus.observed_time:type_name -> google.protobuf.Timestamp + 308, // 102: openshell.v1.ProviderReadinessStatus.evaluated_time:type_name -> google.protobuf.Timestamp 82, // 103: openshell.v1.ProviderReadinessStatus.operation:type_name -> openshell.v1.ConfigUpdateOperation - 306, // 104: openshell.v1.GetSandboxProviderStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 104: openshell.v1.GetSandboxProviderStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 85, // 105: openshell.v1.GetSandboxProviderStatusResponse.status:type_name -> openshell.v1.ProviderReadinessStatus 84, // 106: openshell.v1.ReportProviderReadinessRequest.observation:type_name -> openshell.v1.ProviderReadinessObservation - 305, // 107: openshell.v1.ReportProviderReadinessResponse.report_interval:type_name -> google.protobuf.Duration - 305, // 108: openshell.v1.ReportProviderReadinessResponse.observation_ttl:type_name -> google.protobuf.Duration + 312, // 107: openshell.v1.ReportProviderReadinessResponse.report_interval:type_name -> google.protobuf.Duration + 312, // 108: openshell.v1.ReportProviderReadinessResponse.observation_ttl:type_name -> google.protobuf.Duration 18, // 109: openshell.v1.DeleteSandboxResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 306, // 110: openshell.v1.CreateSshSessionRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 301, // 111: openshell.v1.CreateSshSessionResponse.expiration_time:type_name -> google.protobuf.Timestamp - 306, // 112: openshell.v1.ExposeServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 110: openshell.v1.CreateSshSessionRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 111: openshell.v1.CreateSshSessionResponse.expiration_time:type_name -> google.protobuf.Timestamp + 313, // 112: openshell.v1.ExposeServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 20, // 113: openshell.v1.ExposeServiceRequest.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode - 306, // 114: openshell.v1.GetServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 115: openshell.v1.ListServicesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 114: openshell.v1.GetServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 115: openshell.v1.ListServicesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 100, // 116: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse - 306, // 117: openshell.v1.DeleteServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 117: openshell.v1.DeleteServiceRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 18, // 118: openshell.v1.DeleteServiceResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 302, // 119: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 309, // 119: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 20, // 120: openshell.v1.ServiceEndpoint.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode 99, // 121: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint 18, // 122: openshell.v1.RevokeSshSessionResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 306, // 123: openshell.v1.ExecSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 284, // 124: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry - 305, // 125: openshell.v1.ExecSandboxRequest.execution_timeout:type_name -> google.protobuf.Duration + 313, // 123: openshell.v1.ExecSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 291, // 124: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry + 312, // 125: openshell.v1.ExecSandboxRequest.execution_timeout:type_name -> google.protobuf.Duration 104, // 126: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout 105, // 127: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr 106, // 128: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit @@ -21999,133 +22427,133 @@ var file_openshell_proto_depIdxs = []int32{ 108, // 131: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit 103, // 132: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest 111, // 133: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize - 302, // 134: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 301, // 135: openshell.v1.SshSession.expiration_time:type_name -> google.protobuf.Timestamp - 306, // 136: openshell.v1.WatchSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 301, // 137: openshell.v1.WatchSandboxRequest.since_time:type_name -> google.protobuf.Timestamp + 309, // 134: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 308, // 135: openshell.v1.SshSession.expiration_time:type_name -> google.protobuf.Timestamp + 313, // 136: openshell.v1.WatchSandboxRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 137: openshell.v1.WatchSandboxRequest.since_time:type_name -> google.protobuf.Timestamp 39, // 138: openshell.v1.SandboxStreamEvent.sandbox:type_name -> openshell.v1.Sandbox 115, // 139: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine 53, // 140: openshell.v1.SandboxStreamEvent.event:type_name -> openshell.v1.PlatformEvent 116, // 141: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning 227, // 142: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate - 301, // 143: openshell.v1.SandboxLogLine.event_time:type_name -> google.protobuf.Timestamp - 285, // 144: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry - 306, // 145: openshell.v1.CreateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 307, // 146: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 306, // 147: openshell.v1.GetProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 148: openshell.v1.GetProviderCredentialsRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 305, // 149: openshell.v1.GetProviderCredentialsRequest.minimum_remaining_lifetime:type_name -> google.protobuf.Duration - 301, // 150: openshell.v1.ProviderCredentialValue.expiration_time:type_name -> google.protobuf.Timestamp - 286, // 151: openshell.v1.GetProviderCredentialsResponse.credentials:type_name -> openshell.v1.GetProviderCredentialsResponse.CredentialsEntry - 306, // 152: openshell.v1.ListProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 153: openshell.v1.UpdateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 307, // 154: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 287, // 155: openshell.v1.UpdateProviderRequest.credential_expiration_times:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry - 306, // 156: openshell.v1.DeleteProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 307, // 157: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider + 308, // 143: openshell.v1.SandboxLogLine.event_time:type_name -> google.protobuf.Timestamp + 292, // 144: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry + 313, // 145: openshell.v1.CreateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 314, // 146: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 313, // 147: openshell.v1.GetProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 148: openshell.v1.GetProviderCredentialsRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 312, // 149: openshell.v1.GetProviderCredentialsRequest.minimum_remaining_lifetime:type_name -> google.protobuf.Duration + 308, // 150: openshell.v1.ProviderCredentialValue.expiration_time:type_name -> google.protobuf.Timestamp + 293, // 151: openshell.v1.GetProviderCredentialsResponse.credentials:type_name -> openshell.v1.GetProviderCredentialsResponse.CredentialsEntry + 313, // 152: openshell.v1.ListProvidersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 153: openshell.v1.UpdateProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 314, // 154: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 294, // 155: openshell.v1.UpdateProviderRequest.credential_expiration_times:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry + 313, // 156: openshell.v1.DeleteProviderRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 314, // 157: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider 83, // 158: openshell.v1.ProviderResponse.target_receipts:type_name -> openshell.v1.ProviderMutationReceipt - 307, // 159: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider - 306, // 160: openshell.v1.ListProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 161: openshell.v1.GetProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 314, // 159: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 313, // 160: openshell.v1.ListProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 161: openshell.v1.GetProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 148, // 162: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile - 305, // 163: openshell.v1.ProviderCredentialTokenGrant.cache_ttl:type_name -> google.protobuf.Duration + 312, // 163: openshell.v1.ProviderCredentialTokenGrant.cache_ttl:type_name -> google.protobuf.Duration 131, // 164: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride 8, // 165: openshell.v1.ProviderCredentialTokenGrant.grant_type:type_name -> openshell.v1.ProviderCredentialTokenGrantType 132, // 166: openshell.v1.ProviderCredentialTokenGrant.subject_token:type_name -> openshell.v1.ProviderCredentialTokenGrantSubjectToken 137, // 167: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh 133, // 168: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant 9, // 169: openshell.v1.ProviderCredentialRefresh.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 305, // 170: openshell.v1.ProviderCredentialRefresh.refresh_before:type_name -> google.protobuf.Duration - 305, // 171: openshell.v1.ProviderCredentialRefresh.max_lifetime:type_name -> google.protobuf.Duration + 312, // 170: openshell.v1.ProviderCredentialRefresh.refresh_before:type_name -> google.protobuf.Duration + 312, // 171: openshell.v1.ProviderCredentialRefresh.max_lifetime:type_name -> google.protobuf.Duration 135, // 172: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial 136, // 173: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput 9, // 174: openshell.v1.ProviderCredentialRefreshStatus.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 301, // 175: openshell.v1.ProviderCredentialRefreshStatus.expiration_time:type_name -> google.protobuf.Timestamp - 301, // 176: openshell.v1.ProviderCredentialRefreshStatus.next_refresh_time:type_name -> google.protobuf.Timestamp - 301, // 177: openshell.v1.ProviderCredentialRefreshStatus.last_refresh_time:type_name -> google.protobuf.Timestamp + 308, // 175: openshell.v1.ProviderCredentialRefreshStatus.expiration_time:type_name -> google.protobuf.Timestamp + 308, // 176: openshell.v1.ProviderCredentialRefreshStatus.next_refresh_time:type_name -> google.protobuf.Timestamp + 308, // 177: openshell.v1.ProviderCredentialRefreshStatus.last_refresh_time:type_name -> google.protobuf.Timestamp 16, // 178: openshell.v1.ProviderCredentialRefreshStatus.recovery_action:type_name -> openshell.v1.ProviderCredentialRefreshRecoveryAction - 301, // 179: openshell.v1.ProviderCredentialRefreshStatus.last_error_time:type_name -> google.protobuf.Timestamp - 306, // 180: openshell.v1.GetProviderRefreshStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 179: openshell.v1.ProviderCredentialRefreshStatus.last_error_time:type_name -> google.protobuf.Timestamp + 313, // 180: openshell.v1.GetProviderRefreshStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 138, // 181: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 306, // 182: openshell.v1.ConfigureProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 182: openshell.v1.ConfigureProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 9, // 183: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 288, // 184: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - 301, // 185: openshell.v1.ConfigureProviderRefreshRequest.expiration_time:type_name -> google.protobuf.Timestamp + 295, // 184: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + 308, // 185: openshell.v1.ConfigureProviderRefreshRequest.expiration_time:type_name -> google.protobuf.Timestamp 138, // 186: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 306, // 187: openshell.v1.RotateProviderCredentialRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 187: openshell.v1.RotateProviderCredentialRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 138, // 188: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 306, // 189: openshell.v1.DeleteProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 189: openshell.v1.DeleteProviderRefreshRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 18, // 190: openshell.v1.DeleteProviderRefreshResponse.outcome:type_name -> openshell.v1.DeletionOutcome 10, // 191: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory 134, // 192: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential - 309, // 193: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint - 310, // 194: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 316, // 193: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint + 317, // 194: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary 139, // 195: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery - 289, // 196: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry + 296, // 196: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry 149, // 197: openshell.v1.ProviderProfile.files:type_name -> openshell.v1.ProviderProfileFile 148, // 198: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile 148, // 199: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 306, // 200: openshell.v1.ImportProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 200: openshell.v1.ImportProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 129, // 201: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem 130, // 202: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic 148, // 203: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 306, // 204: openshell.v1.UpdateProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 204: openshell.v1.UpdateProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 129, // 205: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem 130, // 206: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic 148, // 207: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile - 306, // 208: openshell.v1.LintProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 208: openshell.v1.LintProviderProfilesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 129, // 209: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem 130, // 210: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic 18, // 211: openshell.v1.DeleteProviderResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 306, // 212: openshell.v1.DeleteProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 212: openshell.v1.DeleteProviderProfileRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 18, // 213: openshell.v1.DeleteProviderProfileResponse.outcome:type_name -> openshell.v1.DeletionOutcome 162, // 214: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding - 290, // 215: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - 291, // 216: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expiration_times:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry - 292, // 217: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - 293, // 218: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + 297, // 215: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + 298, // 216: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expiration_times:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry + 299, // 217: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + 300, // 218: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry 4, // 219: openshell.v1.GetSandboxProviderEnvironmentResponse.readiness_reason:type_name -> openshell.v1.ProviderReadinessReason - 294, // 220: openshell.v1.GetSandboxProviderEnvironmentResponse.files:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry + 301, // 220: openshell.v1.GetSandboxProviderEnvironmentResponse.files:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.FilesEntry 11, // 221: openshell.v1.ProviderEnvironmentValue.classification:type_name -> openshell.v1.ProviderEnvironmentValueClassification 163, // 222: openshell.v1.ProviderEnvironmentValue.static_credential_binding:type_name -> openshell.v1.StaticCredentialBinding - 301, // 223: openshell.v1.ProviderEnvironmentValue.expiration_time:type_name -> google.protobuf.Timestamp + 308, // 223: openshell.v1.ProviderEnvironmentValue.expiration_time:type_name -> google.protobuf.Timestamp 165, // 224: openshell.v1.ProviderEnvironmentSnapshot.values:type_name -> openshell.v1.ProviderEnvironmentValue - 295, // 225: openshell.v1.ProviderEnvironmentSnapshot.dynamic_credentials:type_name -> openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry + 302, // 225: openshell.v1.ProviderEnvironmentSnapshot.dynamic_credentials:type_name -> openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry 4, // 226: openshell.v1.ProviderEnvironmentSnapshot.readiness_reason:type_name -> openshell.v1.ProviderReadinessReason - 296, // 227: openshell.v1.ProviderEnvironmentSnapshot.files:type_name -> openshell.v1.ProviderEnvironmentSnapshot.FilesEntry - 305, // 228: openshell.v1.ExchangeProviderSubjectTokenResponse.expires_after:type_name -> google.protobuf.Duration - 306, // 229: openshell.v1.UpdateConfigRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 303, // 230: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 311, // 231: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue + 303, // 227: openshell.v1.ProviderEnvironmentSnapshot.files:type_name -> openshell.v1.ProviderEnvironmentSnapshot.FilesEntry + 312, // 228: openshell.v1.ExchangeProviderSubjectTokenResponse.expires_after:type_name -> google.protobuf.Duration + 313, // 229: openshell.v1.UpdateConfigRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 310, // 230: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 318, // 231: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue 170, // 232: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation - 297, // 233: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry + 304, // 233: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry 171, // 234: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule 172, // 235: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint 173, // 236: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule 175, // 237: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules 176, // 238: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules 177, // 239: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary - 312, // 240: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 310, // 241: openshell.v1.L7RuleTarget.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 313, // 242: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule + 319, // 240: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 317, // 241: openshell.v1.L7RuleTarget.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 320, // 242: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule 174, // 243: openshell.v1.AddDenyRules.target:type_name -> openshell.v1.L7RuleTarget - 314, // 244: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule + 321, // 244: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule 174, // 245: openshell.v1.AddAllowRules.target:type_name -> openshell.v1.L7RuleTarget - 298, // 246: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry - 306, // 247: openshell.v1.GetSandboxPolicyStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 305, // 246: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry + 313, // 247: openshell.v1.GetSandboxPolicyStatusRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 188, // 248: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision - 306, // 249: openshell.v1.ListSandboxPoliciesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 249: openshell.v1.ListSandboxPoliciesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 188, // 250: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision 13, // 251: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus 12, // 252: openshell.v1.SandboxConfigurationAdmission.state:type_name -> openshell.v1.ConfigurationAdmissionState 185, // 253: openshell.v1.ReportSandboxConfigurationRequest.admission:type_name -> openshell.v1.SandboxConfigurationAdmission 13, // 254: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus - 301, // 255: openshell.v1.SandboxPolicyRevision.created_time:type_name -> google.protobuf.Timestamp - 301, // 256: openshell.v1.SandboxPolicyRevision.loaded_time:type_name -> google.protobuf.Timestamp - 303, // 257: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 299, // 258: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry - 306, // 259: openshell.v1.GetSandboxLogsRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 301, // 260: openshell.v1.GetSandboxLogsRequest.since_time:type_name -> google.protobuf.Timestamp + 308, // 255: openshell.v1.SandboxPolicyRevision.created_time:type_name -> google.protobuf.Timestamp + 308, // 256: openshell.v1.SandboxPolicyRevision.loaded_time:type_name -> google.protobuf.Timestamp + 310, // 257: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 306, // 258: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry + 313, // 259: openshell.v1.GetSandboxLogsRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 260: openshell.v1.GetSandboxLogsRequest.since_time:type_name -> google.protobuf.Timestamp 115, // 261: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine 115, // 262: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine 195, // 263: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello @@ -22143,8 +22571,8 @@ var file_openshell_proto_depIdxs = []int32{ 197, // 275: openshell.v1.GatewayMessage.config_update:type_name -> openshell.v1.ConfigUpdate 273, // 276: openshell.v1.GatewayMessage.service_route_lease:type_name -> openshell.v1.ServiceRouteLease 197, // 277: openshell.v1.SessionAccepted.bootstrap:type_name -> openshell.v1.ConfigUpdate - 305, // 278: openshell.v1.SessionAccepted.heartbeat_interval:type_name -> google.protobuf.Duration - 315, // 279: openshell.v1.ConfigUpdate.sandbox_config:type_name -> openshell.sandbox.v1.SandboxConfigSnapshot + 312, // 278: openshell.v1.SessionAccepted.heartbeat_interval:type_name -> google.protobuf.Duration + 322, // 279: openshell.v1.ConfigUpdate.sandbox_config:type_name -> openshell.sandbox.v1.SandboxConfigSnapshot 166, // 280: openshell.v1.ConfigUpdate.provider_environment:type_name -> openshell.v1.ProviderEnvironmentSnapshot 6, // 281: openshell.v1.ConfigUpdateResult.outcome:type_name -> openshell.v1.ConfigApplyOutcome 198, // 282: openshell.v1.ConfigUpdateResult.failure:type_name -> openshell.v1.ConfigApplyFailure @@ -22157,50 +22585,50 @@ var file_openshell_proto_depIdxs = []int32{ 214, // 289: openshell.v1.PeerRelayFrame.init:type_name -> openshell.v1.PeerRelayInit 216, // 290: openshell.v1.PeerNotifyConfigUpdateRequest.sandbox:type_name -> openshell.v1.PeerConfigSandboxTarget 217, // 291: openshell.v1.PeerNotifyConfigUpdateRequest.provider:type_name -> openshell.v1.PeerConfigProviderTarget - 301, // 292: openshell.v1.DenialSummary.first_seen_time:type_name -> google.protobuf.Timestamp - 301, // 293: openshell.v1.DenialSummary.last_seen_time:type_name -> google.protobuf.Timestamp + 308, // 292: openshell.v1.DenialSummary.first_seen_time:type_name -> google.protobuf.Timestamp + 308, // 293: openshell.v1.DenialSummary.last_seen_time:type_name -> google.protobuf.Timestamp 222, // 294: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample 224, // 295: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount - 312, // 296: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 301, // 297: openshell.v1.PolicyChunk.created_time:type_name -> google.protobuf.Timestamp - 301, // 298: openshell.v1.PolicyChunk.decided_time:type_name -> google.protobuf.Timestamp - 301, // 299: openshell.v1.PolicyChunk.first_seen_time:type_name -> google.protobuf.Timestamp - 301, // 300: openshell.v1.PolicyChunk.last_seen_time:type_name -> google.protobuf.Timestamp - 303, // 301: openshell.v1.PolicyChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 303, // 302: openshell.v1.PolicyChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 306, // 303: openshell.v1.SubmitPolicyAnalysisRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 319, // 296: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 308, // 297: openshell.v1.PolicyChunk.created_time:type_name -> google.protobuf.Timestamp + 308, // 298: openshell.v1.PolicyChunk.decided_time:type_name -> google.protobuf.Timestamp + 308, // 299: openshell.v1.PolicyChunk.first_seen_time:type_name -> google.protobuf.Timestamp + 308, // 300: openshell.v1.PolicyChunk.last_seen_time:type_name -> google.protobuf.Timestamp + 310, // 301: openshell.v1.PolicyChunk.current_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 310, // 302: openshell.v1.PolicyChunk.candidate_effective_policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 313, // 303: openshell.v1.SubmitPolicyAnalysisRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 223, // 304: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary 226, // 305: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk 225, // 306: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary - 306, // 307: openshell.v1.GetDraftPolicyRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 307: openshell.v1.GetDraftPolicyRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 226, // 308: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk - 301, // 309: openshell.v1.GetDraftPolicyResponse.last_analyzed_time:type_name -> google.protobuf.Timestamp - 306, // 310: openshell.v1.ApproveDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 311: openshell.v1.RejectDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 312: openshell.v1.ApproveAllDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 309: openshell.v1.GetDraftPolicyResponse.last_analyzed_time:type_name -> google.protobuf.Timestamp + 313, // 310: openshell.v1.ApproveDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 311: openshell.v1.RejectDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 312: openshell.v1.ApproveAllDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 236, // 313: openshell.v1.ApproveAllDraftChunksRequest.approvals:type_name -> openshell.v1.DraftChunkApproval - 306, // 314: openshell.v1.EditDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 312, // 315: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 306, // 316: openshell.v1.UndoDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 317: openshell.v1.ClearDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 306, // 318: openshell.v1.GetDraftHistoryRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector - 301, // 319: openshell.v1.DraftHistoryEntry.event_time:type_name -> google.protobuf.Timestamp + 313, // 314: openshell.v1.EditDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 319, // 315: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 313, // 316: openshell.v1.UndoDraftChunkRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 317: openshell.v1.ClearDraftChunksRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 318: openshell.v1.GetDraftHistoryRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 308, // 319: openshell.v1.DraftHistoryEntry.event_time:type_name -> google.protobuf.Timestamp 246, // 320: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry - 300, // 321: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry - 316, // 322: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 316, // 323: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 316, // 324: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace + 307, // 321: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry + 323, // 322: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 323, // 323: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 323, // 324: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace 18, // 325: openshell.v1.DeleteWorkspaceResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 302, // 326: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 309, // 326: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 15, // 327: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole - 306, // 328: openshell.v1.AddWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 328: openshell.v1.AddWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 15, // 329: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole 256, // 330: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember - 306, // 331: openshell.v1.RemoveWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 331: openshell.v1.RemoveWorkspaceMemberRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 18, // 332: openshell.v1.RemoveWorkspaceMemberResponse.outcome:type_name -> openshell.v1.DeletionOutcome - 306, // 333: openshell.v1.ListWorkspaceMembersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 313, // 333: openshell.v1.ListWorkspaceMembersRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector 256, // 334: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember - 301, // 335: openshell.v1.ExtensionServiceCredential.expiration_time:type_name -> google.protobuf.Timestamp + 308, // 335: openshell.v1.ExtensionServiceCredential.expiration_time:type_name -> google.protobuf.Timestamp 19, // 336: openshell.v1.EndpointObservation.result:type_name -> openshell.v1.EndpointResult 272, // 337: openshell.v1.EndpointObservation.failure:type_name -> openshell.v1.EndpointFailure 264, // 338: openshell.v1.ReportEndpointStatusRequest.observations:type_name -> openshell.v1.EndpointObservation @@ -22208,206 +22636,217 @@ var file_openshell_proto_depIdxs = []int32{ 267, // 340: openshell.v1.TokenGrantStatus.last_failure:type_name -> openshell.v1.TokenGrantFailureObservation 272, // 341: openshell.v1.TokenGrantFailureObservation.failure:type_name -> openshell.v1.EndpointFailure 19, // 342: openshell.v1.EndpointStatus.last_result:type_name -> openshell.v1.EndpointResult - 301, // 343: openshell.v1.EndpointStatus.last_reported_time:type_name -> google.protobuf.Timestamp + 308, // 343: openshell.v1.EndpointStatus.last_reported_time:type_name -> google.protobuf.Timestamp 272, // 344: openshell.v1.EndpointStatus.last_failure:type_name -> openshell.v1.EndpointFailure - 301, // 345: openshell.v1.SandboxProvisioning.configuration_change_time:type_name -> google.protobuf.Timestamp - 301, // 346: openshell.v1.SandboxProvisioning.first_rejection_time:type_name -> google.protobuf.Timestamp - 301, // 347: openshell.v1.SandboxProvisioning.deadline:type_name -> google.protobuf.Timestamp - 301, // 348: openshell.v1.SandboxProvisioning.timeout_time:type_name -> google.protobuf.Timestamp - 301, // 349: openshell.v1.SandboxProvisioning.cleanup_completed_time:type_name -> google.protobuf.Timestamp - 301, // 350: openshell.v1.SandboxProvisioning.cleanup_retry_time:type_name -> google.protobuf.Timestamp - 301, // 351: openshell.v1.SandboxProvisioning.attachment_change_time:type_name -> google.protobuf.Timestamp - 301, // 352: openshell.v1.SandboxProvisioning.preparation_deadline:type_name -> google.protobuf.Timestamp - 301, // 353: openshell.v1.SandboxProvisioning.admission_start_time:type_name -> google.protobuf.Timestamp + 308, // 345: openshell.v1.SandboxProvisioning.configuration_change_time:type_name -> google.protobuf.Timestamp + 308, // 346: openshell.v1.SandboxProvisioning.first_rejection_time:type_name -> google.protobuf.Timestamp + 308, // 347: openshell.v1.SandboxProvisioning.deadline:type_name -> google.protobuf.Timestamp + 308, // 348: openshell.v1.SandboxProvisioning.timeout_time:type_name -> google.protobuf.Timestamp + 308, // 349: openshell.v1.SandboxProvisioning.cleanup_completed_time:type_name -> google.protobuf.Timestamp + 308, // 350: openshell.v1.SandboxProvisioning.cleanup_retry_time:type_name -> google.protobuf.Timestamp + 308, // 351: openshell.v1.SandboxProvisioning.attachment_change_time:type_name -> google.protobuf.Timestamp + 308, // 352: openshell.v1.SandboxProvisioning.preparation_deadline:type_name -> google.protobuf.Timestamp + 308, // 353: openshell.v1.SandboxProvisioning.admission_start_time:type_name -> google.protobuf.Timestamp 20, // 354: openshell.v1.SandboxServiceExposure.authorization_mode:type_name -> openshell.v1.ServiceAuthorizationMode 21, // 355: openshell.v1.EndpointFailure.domain:type_name -> openshell.v1.EndpointFailureDomain 16, // 356: openshell.v1.EndpointFailure.recovery_action:type_name -> openshell.v1.ProviderCredentialRefreshRecoveryAction - 305, // 357: openshell.v1.ServiceRouteLease.duration:type_name -> google.protobuf.Duration - 301, // 358: openshell.v1.ServiceRouteLease.expires_at:type_name -> google.protobuf.Timestamp - 317, // 359: openshell.v1.SupervisorServiceAdvertisement.routes:type_name -> openshell.sandbox.v1.SandboxServiceRoute - 120, // 360: openshell.v1.GetProviderCredentialsResponse.CredentialsEntry.value:type_name -> openshell.v1.ProviderCredentialValue - 301, // 361: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp - 301, // 362: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp - 134, // 363: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential - 163, // 364: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding - 134, // 365: openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential - 26, // 366: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest - 28, // 367: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest - 30, // 368: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest - 54, // 369: openshell.v1.OpenShell.CreateSandbox:input_type -> openshell.v1.CreateSandboxRequest - 62, // 370: openshell.v1.OpenShell.BeginRootfsTarStaging:input_type -> openshell.v1.BeginRootfsTarStagingRequest - 64, // 371: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest - 65, // 372: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest - 55, // 373: openshell.v1.OpenShell.CreateSandboxTemplate:input_type -> openshell.v1.CreateSandboxTemplateRequest - 56, // 374: openshell.v1.OpenShell.GetSandboxTemplate:input_type -> openshell.v1.GetSandboxTemplateRequest - 57, // 375: openshell.v1.OpenShell.ListSandboxTemplates:input_type -> openshell.v1.ListSandboxTemplatesRequest - 58, // 376: openshell.v1.OpenShell.DeleteSandboxTemplate:input_type -> openshell.v1.DeleteSandboxTemplateRequest - 66, // 377: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest - 67, // 378: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest - 68, // 379: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest - 86, // 380: openshell.v1.OpenShell.GetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest - 69, // 381: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest - 70, // 382: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest - 71, // 383: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest - 72, // 384: openshell.v1.OpenShell.SuspendSandbox:input_type -> openshell.v1.SuspendSandboxRequest - 73, // 385: openshell.v1.OpenShell.ResumeSandbox:input_type -> openshell.v1.ResumeSandboxRequest - 91, // 386: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest - 93, // 387: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest - 94, // 388: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest - 95, // 389: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest - 97, // 390: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest - 101, // 391: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest - 103, // 392: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest - 109, // 393: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame - 110, // 394: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput - 117, // 395: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest - 118, // 396: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest - 119, // 397: openshell.v1.OpenShell.GetProviderCredentials:input_type -> openshell.v1.GetProviderCredentialsRequest - 122, // 398: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest - 127, // 399: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest - 128, // 400: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest - 152, // 401: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest - 154, // 402: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest - 156, // 403: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest - 123, // 404: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest - 140, // 405: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest - 142, // 406: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest - 144, // 407: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest - 146, // 408: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest - 124, // 409: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest - 159, // 410: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest - 318, // 411: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest - 319, // 412: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest - 169, // 413: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest - 179, // 414: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest - 181, // 415: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest - 183, // 416: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest - 265, // 417: openshell.v1.OpenShell.ReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest - 88, // 418: openshell.v1.OpenShell.ReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest - 186, // 419: openshell.v1.OpenShell.ReportSandboxConfiguration:input_type -> openshell.v1.ReportSandboxConfigurationRequest - 161, // 420: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest - 167, // 421: openshell.v1.OpenShell.ExchangeProviderSubjectToken:input_type -> openshell.v1.ExchangeProviderSubjectTokenRequest - 189, // 422: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest - 190, // 423: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest - 193, // 424: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage - 205, // 425: openshell.v1.OpenShell.ReportMainProcessExit:input_type -> openshell.v1.ReportMainProcessExitRequest - 207, // 426: openshell.v1.OpenShell.FinalizeMainProcessExit:input_type -> openshell.v1.FinalizeMainProcessExitRequest - 213, // 427: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame - 215, // 428: openshell.v1.OpenShell.PeerRelay:input_type -> openshell.v1.PeerRelayFrame - 88, // 429: openshell.v1.OpenShell.PeerReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest - 265, // 430: openshell.v1.OpenShell.PeerReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest - 86, // 431: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest - 218, // 432: openshell.v1.OpenShell.PeerNotifyConfigUpdate:input_type -> openshell.v1.PeerNotifyConfigUpdateRequest - 113, // 433: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest - 228, // 434: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest - 230, // 435: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest - 232, // 436: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest - 234, // 437: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest - 237, // 438: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest - 239, // 439: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest - 241, // 440: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest - 243, // 441: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest - 245, // 442: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest - 22, // 443: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest - 24, // 444: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest - 248, // 445: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest - 250, // 446: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest - 252, // 447: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest - 254, // 448: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest - 257, // 449: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest - 259, // 450: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest - 261, // 451: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest - 27, // 452: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse - 29, // 453: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse - 31, // 454: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse - 74, // 455: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse - 63, // 456: openshell.v1.OpenShell.BeginRootfsTarStaging:output_type -> openshell.v1.BeginRootfsTarStagingResponse - 74, // 457: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse - 75, // 458: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse - 59, // 459: openshell.v1.OpenShell.CreateSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse - 59, // 460: openshell.v1.OpenShell.GetSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse - 60, // 461: openshell.v1.OpenShell.ListSandboxTemplates:output_type -> openshell.v1.ListSandboxTemplatesResponse - 61, // 462: openshell.v1.OpenShell.DeleteSandboxTemplate:output_type -> openshell.v1.DeleteSandboxTemplateResponse - 76, // 463: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse - 77, // 464: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse - 78, // 465: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse - 87, // 466: openshell.v1.OpenShell.GetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse - 90, // 467: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse - 74, // 468: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse - 74, // 469: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse - 74, // 470: openshell.v1.OpenShell.SuspendSandbox:output_type -> openshell.v1.SandboxResponse - 74, // 471: openshell.v1.OpenShell.ResumeSandbox:output_type -> openshell.v1.SandboxResponse - 92, // 472: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse - 100, // 473: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse - 100, // 474: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse - 96, // 475: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse - 98, // 476: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse - 102, // 477: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse - 107, // 478: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent - 109, // 479: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame - 107, // 480: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent - 125, // 481: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse - 125, // 482: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse - 121, // 483: openshell.v1.OpenShell.GetProviderCredentials:output_type -> openshell.v1.GetProviderCredentialsResponse - 126, // 484: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse - 151, // 485: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse - 150, // 486: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse - 153, // 487: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse - 155, // 488: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse - 157, // 489: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse - 125, // 490: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse - 141, // 491: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse - 143, // 492: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse - 145, // 493: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse - 147, // 494: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse - 158, // 495: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse - 160, // 496: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse - 320, // 497: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse - 321, // 498: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse - 178, // 499: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse - 180, // 500: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse - 182, // 501: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse - 184, // 502: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse - 268, // 503: openshell.v1.OpenShell.ReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse - 89, // 504: openshell.v1.OpenShell.ReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse - 187, // 505: openshell.v1.OpenShell.ReportSandboxConfiguration:output_type -> openshell.v1.ReportSandboxConfigurationResponse - 164, // 506: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse - 168, // 507: openshell.v1.OpenShell.ExchangeProviderSubjectToken:output_type -> openshell.v1.ExchangeProviderSubjectTokenResponse - 192, // 508: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse - 191, // 509: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse - 194, // 510: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage - 206, // 511: openshell.v1.OpenShell.ReportMainProcessExit:output_type -> openshell.v1.ReportMainProcessExitResponse - 208, // 512: openshell.v1.OpenShell.FinalizeMainProcessExit:output_type -> openshell.v1.FinalizeMainProcessExitResponse - 213, // 513: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame - 215, // 514: openshell.v1.OpenShell.PeerRelay:output_type -> openshell.v1.PeerRelayFrame - 89, // 515: openshell.v1.OpenShell.PeerReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse - 268, // 516: openshell.v1.OpenShell.PeerReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse - 87, // 517: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse - 219, // 518: openshell.v1.OpenShell.PeerNotifyConfigUpdate:output_type -> openshell.v1.PeerNotifyConfigUpdateResponse - 114, // 519: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent - 229, // 520: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse - 231, // 521: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse - 233, // 522: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse - 235, // 523: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse - 238, // 524: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse - 240, // 525: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse - 242, // 526: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse - 244, // 527: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse - 247, // 528: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse - 23, // 529: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse - 25, // 530: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse - 249, // 531: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse - 251, // 532: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse - 253, // 533: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse - 255, // 534: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse - 258, // 535: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse - 260, // 536: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse - 262, // 537: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse - 452, // [452:538] is the sub-list for method output_type - 366, // [366:452] is the sub-list for method input_type - 366, // [366:366] is the sub-list for extension type_name - 366, // [366:366] is the sub-list for extension extendee - 0, // [0:366] is the sub-list for field type_name + 312, // 357: openshell.v1.ServiceRouteLease.duration:type_name -> google.protobuf.Duration + 308, // 358: openshell.v1.ServiceRouteLease.expires_at:type_name -> google.protobuf.Timestamp + 324, // 359: openshell.v1.SupervisorServiceAdvertisement.routes:type_name -> openshell.sandbox.v1.SandboxServiceRoute + 313, // 360: openshell.v1.GetServiceRouteSnapshotRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 279, // 361: openshell.v1.GetServiceRouteSnapshotResponse.snapshot:type_name -> openshell.v1.ServiceRouteSnapshot + 313, // 362: openshell.v1.WatchServiceRoutesRequest.workspace_scope:type_name -> openshell.datamodel.v1.WorkspaceSelector + 279, // 363: openshell.v1.WatchServiceRoutesResponse.snapshot:type_name -> openshell.v1.ServiceRouteSnapshot + 281, // 364: openshell.v1.ServiceRouteSnapshot.routes:type_name -> openshell.v1.DiscoveredServiceRoute + 280, // 365: openshell.v1.DiscoveredServiceRoute.endpoint:type_name -> openshell.v1.ServiceRouteEndpoint + 308, // 366: openshell.v1.DiscoveredServiceRoute.expires_at:type_name -> google.protobuf.Timestamp + 120, // 367: openshell.v1.GetProviderCredentialsResponse.CredentialsEntry.value:type_name -> openshell.v1.ProviderCredentialValue + 308, // 368: openshell.v1.UpdateProviderRequest.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp + 308, // 369: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpirationTimesEntry.value:type_name -> google.protobuf.Timestamp + 134, // 370: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential + 163, // 371: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding + 134, // 372: openshell.v1.ProviderEnvironmentSnapshot.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential + 26, // 373: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest + 28, // 374: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest + 30, // 375: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest + 54, // 376: openshell.v1.OpenShell.CreateSandbox:input_type -> openshell.v1.CreateSandboxRequest + 62, // 377: openshell.v1.OpenShell.BeginRootfsTarStaging:input_type -> openshell.v1.BeginRootfsTarStagingRequest + 64, // 378: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest + 65, // 379: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest + 55, // 380: openshell.v1.OpenShell.CreateSandboxTemplate:input_type -> openshell.v1.CreateSandboxTemplateRequest + 56, // 381: openshell.v1.OpenShell.GetSandboxTemplate:input_type -> openshell.v1.GetSandboxTemplateRequest + 57, // 382: openshell.v1.OpenShell.ListSandboxTemplates:input_type -> openshell.v1.ListSandboxTemplatesRequest + 58, // 383: openshell.v1.OpenShell.DeleteSandboxTemplate:input_type -> openshell.v1.DeleteSandboxTemplateRequest + 66, // 384: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest + 67, // 385: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest + 68, // 386: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest + 86, // 387: openshell.v1.OpenShell.GetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest + 69, // 388: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest + 70, // 389: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest + 71, // 390: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest + 72, // 391: openshell.v1.OpenShell.SuspendSandbox:input_type -> openshell.v1.SuspendSandboxRequest + 73, // 392: openshell.v1.OpenShell.ResumeSandbox:input_type -> openshell.v1.ResumeSandboxRequest + 91, // 393: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest + 93, // 394: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest + 94, // 395: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest + 95, // 396: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest + 275, // 397: openshell.v1.OpenShell.GetServiceRouteSnapshot:input_type -> openshell.v1.GetServiceRouteSnapshotRequest + 277, // 398: openshell.v1.OpenShell.WatchServiceRoutes:input_type -> openshell.v1.WatchServiceRoutesRequest + 97, // 399: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest + 101, // 400: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest + 103, // 401: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest + 109, // 402: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame + 110, // 403: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput + 117, // 404: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest + 118, // 405: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest + 119, // 406: openshell.v1.OpenShell.GetProviderCredentials:input_type -> openshell.v1.GetProviderCredentialsRequest + 122, // 407: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest + 127, // 408: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest + 128, // 409: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest + 152, // 410: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest + 154, // 411: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest + 156, // 412: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest + 123, // 413: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest + 140, // 414: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest + 142, // 415: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest + 144, // 416: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest + 146, // 417: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest + 124, // 418: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest + 159, // 419: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest + 325, // 420: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest + 326, // 421: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest + 169, // 422: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest + 179, // 423: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest + 181, // 424: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest + 183, // 425: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest + 265, // 426: openshell.v1.OpenShell.ReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest + 88, // 427: openshell.v1.OpenShell.ReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest + 186, // 428: openshell.v1.OpenShell.ReportSandboxConfiguration:input_type -> openshell.v1.ReportSandboxConfigurationRequest + 161, // 429: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest + 167, // 430: openshell.v1.OpenShell.ExchangeProviderSubjectToken:input_type -> openshell.v1.ExchangeProviderSubjectTokenRequest + 189, // 431: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest + 190, // 432: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest + 193, // 433: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage + 205, // 434: openshell.v1.OpenShell.ReportMainProcessExit:input_type -> openshell.v1.ReportMainProcessExitRequest + 207, // 435: openshell.v1.OpenShell.FinalizeMainProcessExit:input_type -> openshell.v1.FinalizeMainProcessExitRequest + 213, // 436: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame + 215, // 437: openshell.v1.OpenShell.PeerRelay:input_type -> openshell.v1.PeerRelayFrame + 88, // 438: openshell.v1.OpenShell.PeerReportProviderReadiness:input_type -> openshell.v1.ReportProviderReadinessRequest + 265, // 439: openshell.v1.OpenShell.PeerReportEndpointStatus:input_type -> openshell.v1.ReportEndpointStatusRequest + 86, // 440: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:input_type -> openshell.v1.GetSandboxProviderStatusRequest + 218, // 441: openshell.v1.OpenShell.PeerNotifyConfigUpdate:input_type -> openshell.v1.PeerNotifyConfigUpdateRequest + 113, // 442: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest + 228, // 443: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest + 230, // 444: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest + 232, // 445: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest + 234, // 446: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest + 237, // 447: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest + 239, // 448: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest + 241, // 449: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest + 243, // 450: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest + 245, // 451: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest + 22, // 452: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest + 24, // 453: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest + 248, // 454: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest + 250, // 455: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest + 252, // 456: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest + 254, // 457: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest + 257, // 458: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest + 259, // 459: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest + 261, // 460: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest + 27, // 461: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse + 29, // 462: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse + 31, // 463: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse + 74, // 464: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse + 63, // 465: openshell.v1.OpenShell.BeginRootfsTarStaging:output_type -> openshell.v1.BeginRootfsTarStagingResponse + 74, // 466: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse + 75, // 467: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse + 59, // 468: openshell.v1.OpenShell.CreateSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse + 59, // 469: openshell.v1.OpenShell.GetSandboxTemplate:output_type -> openshell.v1.SandboxTemplateResponse + 60, // 470: openshell.v1.OpenShell.ListSandboxTemplates:output_type -> openshell.v1.ListSandboxTemplatesResponse + 61, // 471: openshell.v1.OpenShell.DeleteSandboxTemplate:output_type -> openshell.v1.DeleteSandboxTemplateResponse + 76, // 472: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse + 77, // 473: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse + 78, // 474: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse + 87, // 475: openshell.v1.OpenShell.GetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse + 90, // 476: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse + 74, // 477: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse + 74, // 478: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse + 74, // 479: openshell.v1.OpenShell.SuspendSandbox:output_type -> openshell.v1.SandboxResponse + 74, // 480: openshell.v1.OpenShell.ResumeSandbox:output_type -> openshell.v1.SandboxResponse + 92, // 481: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse + 100, // 482: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse + 100, // 483: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse + 96, // 484: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse + 276, // 485: openshell.v1.OpenShell.GetServiceRouteSnapshot:output_type -> openshell.v1.GetServiceRouteSnapshotResponse + 278, // 486: openshell.v1.OpenShell.WatchServiceRoutes:output_type -> openshell.v1.WatchServiceRoutesResponse + 98, // 487: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse + 102, // 488: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse + 107, // 489: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent + 109, // 490: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame + 107, // 491: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent + 125, // 492: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse + 125, // 493: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse + 121, // 494: openshell.v1.OpenShell.GetProviderCredentials:output_type -> openshell.v1.GetProviderCredentialsResponse + 126, // 495: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse + 151, // 496: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse + 150, // 497: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse + 153, // 498: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse + 155, // 499: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse + 157, // 500: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse + 125, // 501: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse + 141, // 502: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse + 143, // 503: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse + 145, // 504: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse + 147, // 505: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse + 158, // 506: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse + 160, // 507: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse + 327, // 508: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse + 328, // 509: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse + 178, // 510: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse + 180, // 511: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse + 182, // 512: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse + 184, // 513: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse + 268, // 514: openshell.v1.OpenShell.ReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse + 89, // 515: openshell.v1.OpenShell.ReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse + 187, // 516: openshell.v1.OpenShell.ReportSandboxConfiguration:output_type -> openshell.v1.ReportSandboxConfigurationResponse + 164, // 517: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse + 168, // 518: openshell.v1.OpenShell.ExchangeProviderSubjectToken:output_type -> openshell.v1.ExchangeProviderSubjectTokenResponse + 192, // 519: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse + 191, // 520: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse + 194, // 521: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage + 206, // 522: openshell.v1.OpenShell.ReportMainProcessExit:output_type -> openshell.v1.ReportMainProcessExitResponse + 208, // 523: openshell.v1.OpenShell.FinalizeMainProcessExit:output_type -> openshell.v1.FinalizeMainProcessExitResponse + 213, // 524: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame + 215, // 525: openshell.v1.OpenShell.PeerRelay:output_type -> openshell.v1.PeerRelayFrame + 89, // 526: openshell.v1.OpenShell.PeerReportProviderReadiness:output_type -> openshell.v1.ReportProviderReadinessResponse + 268, // 527: openshell.v1.OpenShell.PeerReportEndpointStatus:output_type -> openshell.v1.ReportEndpointStatusResponse + 87, // 528: openshell.v1.OpenShell.PeerGetSandboxProviderStatus:output_type -> openshell.v1.GetSandboxProviderStatusResponse + 219, // 529: openshell.v1.OpenShell.PeerNotifyConfigUpdate:output_type -> openshell.v1.PeerNotifyConfigUpdateResponse + 114, // 530: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent + 229, // 531: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse + 231, // 532: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse + 233, // 533: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse + 235, // 534: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse + 238, // 535: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse + 240, // 536: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse + 242, // 537: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse + 244, // 538: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse + 247, // 539: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse + 23, // 540: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse + 25, // 541: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse + 249, // 542: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse + 251, // 543: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse + 253, // 544: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse + 255, // 545: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse + 258, // 546: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse + 260, // 547: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse + 262, // 548: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse + 461, // [461:549] is the sub-list for method output_type + 373, // [373:461] is the sub-list for method input_type + 373, // [373:373] is the sub-list for extension type_name + 373, // [373:373] is the sub-list for extension extendee + 0, // [0:373] is the sub-list for field type_name } func init() { file_openshell_proto_init() } @@ -22500,7 +22939,7 @@ func file_openshell_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_openshell_proto_rawDesc), len(file_openshell_proto_rawDesc)), NumEnums: 22, - NumMessages: 279, + NumMessages: 286, 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 2f13a80383..a25402b10d 100644 --- a/sdk/go/proto/openshellv1/openshell_grpc.pb.go +++ b/sdk/go/proto/openshellv1/openshell_grpc.pb.go @@ -47,6 +47,8 @@ const ( OpenShell_ExposeService_FullMethodName = "/openshell.v1.OpenShell/ExposeService" OpenShell_GetService_FullMethodName = "/openshell.v1.OpenShell/GetService" OpenShell_ListServices_FullMethodName = "/openshell.v1.OpenShell/ListServices" + OpenShell_GetServiceRouteSnapshot_FullMethodName = "/openshell.v1.OpenShell/GetServiceRouteSnapshot" + OpenShell_WatchServiceRoutes_FullMethodName = "/openshell.v1.OpenShell/WatchServiceRoutes" OpenShell_DeleteService_FullMethodName = "/openshell.v1.OpenShell/DeleteService" OpenShell_RevokeSshSession_FullMethodName = "/openshell.v1.OpenShell/RevokeSshSession" OpenShell_ExecSandbox_FullMethodName = "/openshell.v1.OpenShell/ExecSandbox" @@ -181,6 +183,10 @@ type OpenShellClient interface { GetService(ctx context.Context, in *GetServiceRequest, opts ...grpc.CallOption) (*ServiceEndpointResponse, error) // List sandbox HTTP service endpoints. ListServices(ctx context.Context, in *ListServicesRequest, opts ...grpc.CallOption) (*ListServicesResponse, error) + // Read installed, unexpired application routes in one explicit workspace. + GetServiceRouteSnapshot(ctx context.Context, in *GetServiceRouteSnapshotRequest, opts ...grpc.CallOption) (*GetServiceRouteSnapshotResponse, error) + // Full replacement views; reauthorize during the bounded watch lifetime. + WatchServiceRoutes(ctx context.Context, in *WatchServiceRoutesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[WatchServiceRoutesResponse], error) // Delete one sandbox HTTP service endpoint. DeleteService(ctx context.Context, in *DeleteServiceRequest, opts ...grpc.CallOption) (*DeleteServiceResponse, error) // Revoke a previously issued SSH session. @@ -607,6 +613,35 @@ func (c *openShellClient) ListServices(ctx context.Context, in *ListServicesRequ return out, nil } +func (c *openShellClient) GetServiceRouteSnapshot(ctx context.Context, in *GetServiceRouteSnapshotRequest, opts ...grpc.CallOption) (*GetServiceRouteSnapshotResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetServiceRouteSnapshotResponse) + err := c.cc.Invoke(ctx, OpenShell_GetServiceRouteSnapshot_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *openShellClient) WatchServiceRoutes(ctx context.Context, in *WatchServiceRoutesRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[WatchServiceRoutesResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[0], OpenShell_WatchServiceRoutes_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[WatchServiceRoutesRequest, WatchServiceRoutesResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type OpenShell_WatchServiceRoutesClient = grpc.ServerStreamingClient[WatchServiceRoutesResponse] + func (c *openShellClient) DeleteService(ctx context.Context, in *DeleteServiceRequest, opts ...grpc.CallOption) (*DeleteServiceResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(DeleteServiceResponse) @@ -629,7 +664,7 @@ func (c *openShellClient) RevokeSshSession(ctx context.Context, in *RevokeSshSes func (c *openShellClient) ExecSandbox(ctx context.Context, in *ExecSandboxRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ExecSandboxEvent], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[0], OpenShell_ExecSandbox_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[1], OpenShell_ExecSandbox_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -648,7 +683,7 @@ type OpenShell_ExecSandboxClient = grpc.ServerStreamingClient[ExecSandboxEvent] func (c *openShellClient) ForwardTcp(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[TcpForwardFrame, TcpForwardFrame], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[1], OpenShell_ForwardTcp_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[2], OpenShell_ForwardTcp_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -661,7 +696,7 @@ type OpenShell_ForwardTcpClient = grpc.BidiStreamingClient[TcpForwardFrame, TcpF func (c *openShellClient) ExecSandboxInteractive(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ExecSandboxInput, ExecSandboxEvent], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[2], OpenShell_ExecSandboxInteractive_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[3], OpenShell_ExecSandboxInteractive_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -954,7 +989,7 @@ func (c *openShellClient) GetSandboxLogs(ctx context.Context, in *GetSandboxLogs func (c *openShellClient) PushSandboxLogs(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[PushSandboxLogsRequest, PushSandboxLogsResponse], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[3], OpenShell_PushSandboxLogs_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[4], OpenShell_PushSandboxLogs_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -967,7 +1002,7 @@ type OpenShell_PushSandboxLogsClient = grpc.ClientStreamingClient[PushSandboxLog func (c *openShellClient) ConnectSupervisor(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[SupervisorMessage, GatewayMessage], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[4], OpenShell_ConnectSupervisor_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[5], OpenShell_ConnectSupervisor_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -1000,7 +1035,7 @@ func (c *openShellClient) FinalizeMainProcessExit(ctx context.Context, in *Final func (c *openShellClient) RelayStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[RelayFrame, RelayFrame], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[5], OpenShell_RelayStream_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[6], OpenShell_RelayStream_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -1013,7 +1048,7 @@ type OpenShell_RelayStreamClient = grpc.BidiStreamingClient[RelayFrame, RelayFra func (c *openShellClient) PeerRelay(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[PeerRelayFrame, PeerRelayFrame], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[6], OpenShell_PeerRelay_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[7], OpenShell_PeerRelay_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -1066,7 +1101,7 @@ func (c *openShellClient) PeerNotifyConfigUpdate(ctx context.Context, in *PeerNo 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...) + stream, err := c.cc.NewStream(ctx, &OpenShell_ServiceDesc.Streams[8], OpenShell_WatchSandbox_FullMethodName, cOpts...) if err != nil { return nil, err } @@ -1333,6 +1368,10 @@ type OpenShellServer interface { GetService(context.Context, *GetServiceRequest) (*ServiceEndpointResponse, error) // List sandbox HTTP service endpoints. ListServices(context.Context, *ListServicesRequest) (*ListServicesResponse, error) + // Read installed, unexpired application routes in one explicit workspace. + GetServiceRouteSnapshot(context.Context, *GetServiceRouteSnapshotRequest) (*GetServiceRouteSnapshotResponse, error) + // Full replacement views; reauthorize during the bounded watch lifetime. + WatchServiceRoutes(*WatchServiceRoutesRequest, grpc.ServerStreamingServer[WatchServiceRoutesResponse]) error // Delete one sandbox HTTP service endpoint. DeleteService(context.Context, *DeleteServiceRequest) (*DeleteServiceResponse, error) // Revoke a previously issued SSH session. @@ -1591,6 +1630,12 @@ func (UnimplementedOpenShellServer) GetService(context.Context, *GetServiceReque func (UnimplementedOpenShellServer) ListServices(context.Context, *ListServicesRequest) (*ListServicesResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListServices not implemented") } +func (UnimplementedOpenShellServer) GetServiceRouteSnapshot(context.Context, *GetServiceRouteSnapshotRequest) (*GetServiceRouteSnapshotResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetServiceRouteSnapshot not implemented") +} +func (UnimplementedOpenShellServer) WatchServiceRoutes(*WatchServiceRoutesRequest, grpc.ServerStreamingServer[WatchServiceRoutesResponse]) error { + return status.Error(codes.Unimplemented, "method WatchServiceRoutes not implemented") +} func (UnimplementedOpenShellServer) DeleteService(context.Context, *DeleteServiceRequest) (*DeleteServiceResponse, error) { return nil, status.Error(codes.Unimplemented, "method DeleteService not implemented") } @@ -2230,6 +2275,35 @@ func _OpenShell_ListServices_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _OpenShell_GetServiceRouteSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetServiceRouteSnapshotRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(OpenShellServer).GetServiceRouteSnapshot(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: OpenShell_GetServiceRouteSnapshot_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(OpenShellServer).GetServiceRouteSnapshot(ctx, req.(*GetServiceRouteSnapshotRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _OpenShell_WatchServiceRoutes_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(WatchServiceRoutesRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(OpenShellServer).WatchServiceRoutes(m, &grpc.GenericServerStream[WatchServiceRoutesRequest, WatchServiceRoutesResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type OpenShell_WatchServiceRoutesServer = grpc.ServerStreamingServer[WatchServiceRoutesResponse] + func _OpenShell_DeleteService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeleteServiceRequest) if err := dec(in); err != nil { @@ -3369,6 +3443,10 @@ var OpenShell_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListServices", Handler: _OpenShell_ListServices_Handler, }, + { + MethodName: "GetServiceRouteSnapshot", + Handler: _OpenShell_GetServiceRouteSnapshot_Handler, + }, { MethodName: "DeleteService", Handler: _OpenShell_DeleteService_Handler, @@ -3587,6 +3665,11 @@ var OpenShell_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{ + { + StreamName: "WatchServiceRoutes", + Handler: _OpenShell_WatchServiceRoutes_Handler, + ServerStreams: true, + }, { StreamName: "ExecSandbox", Handler: _OpenShell_ExecSandbox_Handler, diff --git a/skills/debug-openshell-cluster/SKILL.md b/skills/debug-openshell-cluster/SKILL.md index 59246aa16d..2f9159851b 100644 --- a/skills/debug-openshell-cluster/SKILL.md +++ b/skills/debug-openshell-cluster/SKILL.md @@ -1605,8 +1605,8 @@ Service changes arrive through polling or push configuration. Only admitted service declarations are installed. Polling and accepted live push sessions renew a 30-second lease; rejected configuration or expired freshness closes routes. App traffic uses application/edge authentication independently of gateway -user authentication. This listener stage does not add service discovery or -change the public URLs printed by the CLI. +user authentication. The discovery API publishes accepted listener installations; public URLs +printed by the CLI continue to use the gateway path. When enabled application routes are not published, check the authenticated supervisor session and installed configuration before checking ingress. The @@ -1616,7 +1616,14 @@ freshness covers that lease. Replayed, late, stale-configuration, and replaced session reports cannot renew evidence. Endpoint resolution comes from the compute driver; ambiguous shared member ownership must not publish an address. -For shared pools, compare the discovered endpoint to the +For discovery troubleshooting, request `GetServiceRouteSnapshot` for an explicit +active workspace using an identity with `sandbox:read` and workspace user access. +`WatchServiceRoutes` rechecks access every second and ends after one minute; +clients must reconnect/relist. Compare installation versions separately from +snapshot revisions: lease renewal changes expiry and the snapshot revision while +preserving installation identity. Treat unavailable/corrupt/over-limit results as +errors, and expire cached routes independently. Do not turn an error into an +empty replacement. For shared pools, compare the discovered endpoint to the acknowledged owner's Pod IP and configured app port, not its runtime port or a load-balanced supervisor Service. Publication requires a current ownership term, live member, and acknowledged ready report. During takeover old streams may close;