1use anyhow::Result;
2use async_trait::async_trait;
3use serde::{Deserialize, Serialize};
4use std::collections::{BTreeMap, BTreeSet};
5use std::fmt::Debug;
6use std::sync::Arc;
7
8mod base64_bytes {
9 use base64::{Engine as _, engine::general_purpose::STANDARD};
10 use serde::{Deserialize, Deserializer, Serializer};
11
12 pub fn serialize<S>(value: &[u8], serializer: S) -> Result<S::Ok, S::Error>
13 where
14 S: Serializer,
15 {
16 serializer.serialize_str(&STANDARD.encode(value))
17 }
18
19 pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
20 where
21 D: Deserializer<'de>,
22 {
23 let value = String::deserialize(deserializer)?;
24 STANDARD.decode(value).map_err(serde::de::Error::custom)
25 }
26}
27
28mod catalog;
29pub use catalog::*;
30
31mod ports;
32pub use ports::*;
33
34mod owners;
35pub use owners::*;
36
37mod commands;
38pub use commands::*;
39
40mod resources;
41pub use resources::*;
42
43pub const COMPUTERS_PATH: &str = "/internal/v1/workspace/computers";
44pub const COMPUTER_PATH: &str = "/internal/v1/workspace/computers/{computerId}";
45pub const SPACES_PATH: &str = "/internal/v1/workspace/spaces";
46pub const SPACE_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}";
47pub const SPACE_GRANTS_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/grants";
48pub const SPACE_GRANT_REVOKE_PATH: &str =
49 "/internal/v1/workspace/spaces/{spaceId}/grants/{grantId}/revoke";
50pub const SPACE_SESSIONS_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/sessions";
51pub const SPACE_SESSION_HEARTBEAT_PATH: &str =
52 "/internal/v1/workspace/space-sessions/{sessionId}/heartbeat";
53pub const SPACE_SESSION_CLOSE_PATH: &str =
54 "/internal/v1/workspace/space-sessions/{sessionId}/close";
55pub const SPACE_TICKETS_PATH: &str = "/internal/v1/workspace/space-access-tickets";
56pub const SPACE_LEASES_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/leases";
57pub const SPACE_LEASE_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/leases/{leaseId}";
58pub const SPACE_FILES_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/files/{*filePath}";
59pub const SPACE_FILES_READ_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/files/read";
60pub const SPACE_CHANGE_SETS_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/change-sets";
61pub const SPACE_CHANGE_SET_APPLY_PATH: &str =
62 "/internal/v1/workspace/spaces/{spaceId}/change-sets/{changeSetId}/apply";
63pub const SANDBOXES_PATH: &str = "/internal/v1/workspace/sandboxes";
64pub const SANDBOX_PATH: &str = "/internal/v1/workspace/sandboxes/{sandboxId}";
65pub const SANDBOX_STOP_PATH: &str = "/internal/v1/workspace/sandboxes/{sandboxId}/stop";
66pub const SNAPSHOTS_PATH: &str = "/internal/v1/workspace/snapshots";
67pub const SNAPSHOT_PATH: &str = "/internal/v1/workspace/snapshots/{snapshotId}";
68pub const BUILD_BUILTIN_SNAPSHOTS_PATH: &str = "/internal/v1/workspace/snapshots:build-builtin";
69pub const CATALOG_SNAPSHOTS_PATH: &str = "/internal/v1/workspace/snapshots:catalog";
70pub const TEMPLATES_PATH: &str = "/internal/v1/workspace/templates";
71pub const TEMPLATE_VERSIONS_PATH: &str = "/internal/v1/workspace/templates/{templateId}/versions";
72pub const TEMPLATE_VERSION_PATH: &str =
73 "/internal/v1/workspace/templates/{templateId}/versions/{version}";
74pub const TEMPLATE_VERSION_PUBLISH_PATH: &str =
75 "/internal/v1/workspace/templates/{templateId}/versions/{version}/publish";
76pub const TEMPLATE_VERSION_DEPRECATE_PATH: &str =
77 "/internal/v1/workspace/templates/{templateId}/versions/{version}/deprecate";
78pub const DELEGATIONS_PATH: &str = "/internal/v1/workspace/delegations";
79pub const DELEGATION_REVOKE_PATH: &str = "/internal/v1/workspace/delegations/{delegationId}/revoke";
80pub const ENVIRONMENT_MAX_FILE_BYTES: usize = 8 * 1024 * 1024;
81pub const ENVIRONMENT_MAX_PATH_BYTES: usize = 4096;
82
83pub fn space_directory_path(space_id: &str) -> String {
85 format!("spaces/{space_id}")
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
89#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
90pub enum EnvironmentErrorCode {
91 NotFound,
92 Forbidden,
93 Conflict,
94 InvalidState,
95 CapabilityUnsupported,
96 TicketExpired,
97 LeaseRequired,
98 StaleFencingToken,
99 RevisionConflict,
100}
101
102#[derive(Debug, Clone)]
103pub struct EnvironmentDomainError {
104 pub code: EnvironmentErrorCode,
105 pub message: String,
106}
107
108impl EnvironmentDomainError {
109 pub fn new(code: EnvironmentErrorCode, message: impl Into<String>) -> Self {
110 Self {
111 code,
112 message: message.into(),
113 }
114 }
115}
116
117impl std::fmt::Display for EnvironmentDomainError {
118 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 formatter.write_str(&self.message)
120 }
121}
122
123impl std::error::Error for EnvironmentDomainError {}
124
125#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
126#[serde(rename_all = "snake_case")]
127pub enum PrincipalKind {
128 User,
129 Agent,
130}
131
132#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
133#[serde(deny_unknown_fields, rename_all = "camelCase")]
134pub struct PrincipalRef {
135 pub kind: PrincipalKind,
136 pub id: String,
137}
138
139impl PrincipalRef {
140 pub fn user(id: impl Into<String>) -> Self {
141 Self {
142 kind: PrincipalKind::User,
143 id: id.into(),
144 }
145 }
146
147 pub fn agent(id: impl Into<String>) -> Self {
148 Self {
149 kind: PrincipalKind::Agent,
150 id: id.into(),
151 }
152 }
153}
154
155#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
156#[serde(deny_unknown_fields, rename_all = "camelCase")]
157pub struct ResourceScope {
158 pub tenant_id: String,
159 pub project_id: String,
160}
161
162#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
163#[serde(deny_unknown_fields, rename_all = "camelCase")]
164pub struct ProviderResourceRef {
165 pub provider: String,
166 pub external_id: String,
167}
168
169#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
170#[serde(deny_unknown_fields, rename_all = "camelCase")]
171pub struct ProviderCapabilities {
172 #[serde(default)]
173 pub capabilities: BTreeSet<String>,
174}
175
176impl ProviderCapabilities {
177 pub fn supports(&self, capability: &str) -> bool {
178 self.capabilities.contains(capability)
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
183#[serde(rename_all = "snake_case")]
184pub enum ComputerLifecycle {
185 Ready,
186 Deleted,
187}
188
189#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
190#[serde(deny_unknown_fields, rename_all = "camelCase")]
191pub struct ComputerRecord {
192 pub id: String,
193 pub scope: ResourceScope,
194 pub provider_ref: ProviderResourceRef,
195 pub lifecycle: ComputerLifecycle,
196 pub capabilities: ProviderCapabilities,
197 pub owners: Vec<OwnerRef>,
198 pub version: u64,
199 pub created_at_ms: u64,
200 pub updated_at_ms: u64,
201}
202
203#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
204#[serde(deny_unknown_fields, rename_all = "camelCase")]
205pub struct ComputerBinding {
206 pub computer_id: String,
207 pub principal: PrincipalRef,
208 pub role: String,
209 pub active: bool,
210 pub bound_at_ms: u64,
211 #[serde(default, skip_serializing_if = "Option::is_none")]
212 pub released_at_ms: Option<u64>,
213 pub version: u64,
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
217#[serde(rename_all = "snake_case")]
218pub enum SpacePersistence {
219 Persistent,
220 CopyOnWrite,
221}
222
223#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
224#[serde(rename_all = "snake_case")]
225pub enum SpaceLifecycle {
226 Ready,
227 Deleted,
228}
229
230#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
231#[serde(deny_unknown_fields, rename_all = "camelCase")]
232pub struct SpaceRecord {
233 pub id: String,
234 pub computer_id: String,
235 pub scope: ResourceScope,
236 pub persistence: SpacePersistence,
237 pub lifecycle: SpaceLifecycle,
238 pub capabilities: ProviderCapabilities,
239 pub owners: Vec<OwnerRef>,
240 #[serde(default, skip_serializing_if = "Option::is_none")]
241 pub source_snapshot_id: Option<String>,
242 pub revision: u64,
243 pub version: u64,
244 pub created_at_ms: u64,
245 pub updated_at_ms: u64,
246}
247
248#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
249#[serde(rename_all = "snake_case")]
250pub enum SandboxPlacement {
251 Computer(String),
252 ProviderPool(String),
253}
254
255#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
256#[serde(rename_all = "snake_case")]
257pub enum SandboxLifecycle {
258 Ready,
259 Stopped,
260 Expired,
261}
262
263#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
264#[serde(deny_unknown_fields, rename_all = "camelCase")]
265pub struct SandboxMount {
266 pub alias: String,
267 pub space_id: String,
268 pub mode: SpaceAccessMode,
269 #[serde(default, skip_serializing_if = "Option::is_none")]
270 pub path_prefix: Option<String>,
271 pub access_ticket_token: String,
272}
273
274#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
277#[serde(deny_unknown_fields, rename_all = "camelCase")]
278pub struct SandboxMountRecord {
279 pub alias: String,
280 pub space_id: String,
281 pub mode: SpaceAccessMode,
282 #[serde(default, skip_serializing_if = "Option::is_none")]
283 pub path_prefix: Option<String>,
284 pub access_ticket_id: String,
285}
286
287#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
288#[serde(deny_unknown_fields, rename_all = "camelCase")]
289pub struct SandboxRecord {
290 pub id: String,
291 pub scope: ResourceScope,
292 pub provider_ref: ProviderResourceRef,
293 pub placement: SandboxPlacement,
294 pub lifecycle: SandboxLifecycle,
295 pub owners: Vec<OwnerRef>,
296 #[serde(default, skip_serializing_if = "Option::is_none")]
297 pub access_delegation_id: Option<String>,
298 pub capabilities: ProviderCapabilities,
299 #[serde(default)]
300 pub mounts: Vec<SandboxMountRecord>,
301 pub expires_at_ms: u64,
302 pub version: u64,
303 pub created_at_ms: u64,
304 pub updated_at_ms: u64,
305}
306
307#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
308#[serde(rename_all = "snake_case")]
309pub enum SnapshotLifecycle {
310 Building,
311 Ready,
312 Failed,
313 Deleted,
314}
315
316#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
317#[serde(tag = "kind", rename_all = "snake_case")]
318pub enum SnapshotSourceRecord {
319 Build { spec: SnapshotBuildSpec },
320}
321
322#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
323#[serde(deny_unknown_fields, rename_all = "camelCase")]
324pub struct SnapshotRecord {
325 pub id: String,
326 pub scope: ResourceScope,
327 pub provider: String,
328 pub provider_ref: ProviderResourceRef,
329 pub source: SnapshotSourceRecord,
330 pub visibility: SnapshotVisibility,
331 pub owners: Vec<OwnerRef>,
332 #[serde(default)]
333 pub builtin: bool,
334 pub created_by: PrincipalRef,
335 pub lifecycle: SnapshotLifecycle,
336 #[serde(default, skip_serializing_if = "Option::is_none")]
337 pub digest: Option<String>,
338 #[serde(default, skip_serializing_if = "Option::is_none")]
339 pub size_bytes: Option<u64>,
340 #[serde(default, skip_serializing_if = "Option::is_none")]
341 pub error: Option<String>,
342 pub created_at_ms: u64,
343 pub updated_at_ms: u64,
344}
345
346#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
347#[serde(rename_all = "snake_case")]
348pub enum TemplateTarget {
349 Computer,
350 Sandbox,
351}
352
353#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
354#[serde(rename_all = "snake_case")]
355pub enum TemplateVersionState {
356 Draft,
357 Published,
358 Deprecated,
359}
360
361#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
362#[serde(deny_unknown_fields, rename_all = "camelCase")]
363pub struct TemplateVersionRecord {
364 pub template_id: String,
365 pub version: String,
366 pub scope: ResourceScope,
367 pub provider: String,
368 pub created_by: PrincipalRef,
369 #[serde(default, skip_serializing_if = "Option::is_none")]
370 pub provider_template_id: Option<String>,
371 pub target: TemplateTarget,
372 #[serde(default, skip_serializing_if = "Option::is_none")]
373 pub base_snapshot_id: Option<String>,
374 #[serde(default)]
375 pub resource_profile: BTreeMap<String, String>,
376 #[serde(default)]
377 pub parameter_schema: BTreeMap<String, String>,
378 pub state: TemplateVersionState,
379 pub created_at_ms: u64,
380}
381
382#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
383#[serde(rename_all = "snake_case")]
384pub enum SpaceCapability {
385 Read,
386 Write,
387 Share,
388 Manage,
389 Mount,
390 Snapshot,
391 Restore,
392 Delete,
393}
394
395#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
396#[serde(deny_unknown_fields, rename_all = "camelCase")]
397pub struct SpaceGrant {
398 pub id: String,
399 pub scope: ResourceScope,
400 pub space_id: String,
401 pub principal: PrincipalRef,
402 pub capabilities: BTreeSet<SpaceCapability>,
403 #[serde(default)]
404 pub path_prefixes: Vec<String>,
405 #[serde(default, skip_serializing_if = "Option::is_none")]
406 pub expires_at_ms: Option<u64>,
407 pub active: bool,
408 pub version: u64,
409}
410
411#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
412#[serde(rename_all = "snake_case")]
413pub enum SpaceAccessMode {
414 ReadOnly,
415 DirectWrite,
416 CopyOnWrite,
417}
418
419#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
420#[serde(rename_all = "snake_case")]
421pub enum SpaceSessionLifecycle {
422 Opening,
423 Active,
424 Closing,
425 Closed,
426 Expired,
427 Revoked,
428}
429
430#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
431#[serde(deny_unknown_fields, rename_all = "camelCase")]
432pub struct SpaceCollaborationSession {
433 pub id: String,
434 pub scope: ResourceScope,
435 pub space_id: String,
436 pub principal: PrincipalRef,
437 #[serde(default, skip_serializing_if = "Option::is_none")]
438 pub delegation_id: Option<String>,
439 pub requested_mode: SpaceAccessMode,
440 pub effective_mode: SpaceAccessMode,
441 pub lifecycle: SpaceSessionLifecycle,
442 pub last_heartbeat_at_ms: u64,
443 pub expires_at_ms: u64,
444 pub version: u64,
445}
446
447#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
448#[serde(deny_unknown_fields, rename_all = "camelCase")]
449pub struct SpaceAccessTicketRecord {
450 pub id: String,
451 pub token_hash: String,
452 pub scope: ResourceScope,
453 pub space_id: String,
454 pub session_id: String,
455 pub mode: SpaceAccessMode,
456 #[serde(default)]
459 pub capability_paths: BTreeMap<SpaceCapability, Vec<String>>,
460 #[serde(default, skip_serializing_if = "Option::is_none")]
461 pub fencing_token: Option<u64>,
462 pub expires_at_ms: u64,
463 pub revoked: bool,
464}
465
466#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
467#[serde(deny_unknown_fields, rename_all = "camelCase")]
468pub struct IssuedSpaceAccessTicket {
469 pub ticket: SpaceAccessTicketRecord,
470 pub token: String,
473}
474
475#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
476#[serde(deny_unknown_fields, rename_all = "camelCase")]
477pub struct SpaceWriteLease {
478 pub id: String,
479 pub scope: ResourceScope,
480 pub space_id: String,
481 pub session_id: String,
482 pub fencing_token: u64,
483 pub version: u64,
484 pub acquired_at_ms: u64,
485 pub expires_at_ms: u64,
486 pub active: bool,
487}
488
489#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
490#[serde(deny_unknown_fields, rename_all = "camelCase")]
491pub struct DelegationRecord {
492 pub id: String,
493 pub scope: ResourceScope,
494 pub grantor_user_id: String,
495 pub delegate_agent_id: String,
496 #[serde(default)]
497 pub computer_ids: BTreeSet<String>,
498 #[serde(default)]
499 pub space_ids: BTreeSet<String>,
500 pub capabilities: BTreeSet<SpaceCapability>,
501 #[serde(default)]
502 pub path_prefixes: Vec<String>,
503 pub purpose: String,
504 pub expires_at_ms: u64,
505 #[serde(default, skip_serializing_if = "Option::is_none")]
506 pub revoked_at_ms: Option<u64>,
507}
508
509#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
510#[serde(rename_all = "snake_case")]
511pub enum ChangeSetLifecycle {
512 Ready,
513 Applied,
514}
515
516#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
517#[serde(deny_unknown_fields, rename_all = "camelCase")]
518pub struct SpaceChangeSetRecord {
519 pub id: String,
520 pub scope: ResourceScope,
521 pub source_space_id: String,
522 pub target_space_id: String,
523 pub base_revision: u64,
524 pub created_by_session_id: String,
525 #[serde(default, skip_serializing_if = "Option::is_none")]
526 pub provider_change_ref: Option<String>,
527 pub lifecycle: ChangeSetLifecycle,
528 pub created_at_ms: u64,
529}
530
531#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
532#[serde(deny_unknown_fields, rename_all = "camelCase")]
533pub struct CreateComputerRequest {
534 pub provider: String,
535 #[serde(default, skip_serializing_if = "Option::is_none")]
536 pub snapshot_id: Option<String>,
537 #[serde(default, skip_serializing_if = "Option::is_none")]
538 pub template_id: Option<String>,
539 #[serde(default, skip_serializing_if = "Option::is_none")]
540 pub template_version: Option<String>,
541 #[serde(default)]
542 pub profile: BTreeMap<String, String>,
543 #[serde(default)]
545 pub owners: Vec<OwnerRef>,
546}
547
548#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
549#[serde(deny_unknown_fields, rename_all = "camelCase")]
550pub struct CreateSpaceRequest {
551 pub computer_id: String,
552 pub persistence: SpacePersistence,
553 #[serde(default, skip_serializing_if = "Option::is_none")]
554 pub source_snapshot_id: Option<String>,
555 #[serde(default)]
557 pub owners: Vec<OwnerRef>,
558}
559
560#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
561#[serde(deny_unknown_fields, rename_all = "camelCase")]
562pub struct CreateSandboxRequest {
563 pub provider: String,
564 pub placement: SandboxPlacement,
565 #[serde(default, skip_serializing_if = "Option::is_none")]
566 pub delegation_id: Option<String>,
567 pub ttl_ms: u64,
568 #[serde(default)]
569 pub mounts: Vec<SandboxMount>,
570 #[serde(default, skip_serializing_if = "Option::is_none")]
571 pub snapshot_id: Option<String>,
572 #[serde(default, skip_serializing_if = "Option::is_none")]
573 pub template_id: Option<String>,
574 #[serde(default, skip_serializing_if = "Option::is_none")]
575 pub template_version: Option<String>,
576 #[serde(default, skip_serializing_if = "Option::is_none")]
577 pub source_snapshot_id: Option<String>,
578 #[serde(default)]
579 pub profile: BTreeMap<String, String>,
580}
581
582#[derive(Debug, Clone, PartialEq, Eq)]
585pub struct ProviderComputerRequest {
586 pub template_external_id: Option<String>,
587 pub profile: BTreeMap<String, String>,
588}
589
590#[derive(Debug, Clone, PartialEq, Eq)]
591pub struct ProviderSpaceRequest {
592 pub persistence: SpacePersistence,
593 pub source_snapshot_external_id: Option<String>,
594}
595
596#[derive(Debug, Clone, PartialEq, Eq)]
597pub struct ProviderSandboxMount {
598 pub alias: String,
599 pub space_directory: String,
600 pub mode: SpaceAccessMode,
601 pub path_prefix: Option<String>,
602}
603
604#[derive(Debug, Clone, PartialEq, Eq)]
605pub enum ProviderSandboxPlacement {
606 Computer(String),
607 ProviderPool(String),
608}
609
610#[derive(Debug, Clone, PartialEq, Eq)]
611pub struct ProviderSandboxRequest {
612 pub placement: ProviderSandboxPlacement,
613 pub ttl_ms: u64,
614 pub mounts: Vec<ProviderSandboxMount>,
615 pub template_external_id: Option<String>,
616 pub source_snapshot_external_id: Option<String>,
617 pub profile: BTreeMap<String, String>,
618}
619
620#[derive(Debug, Clone, PartialEq, Eq)]
621pub enum ProviderSnapshotSource {
622 Computer(String),
623 Sandbox(String),
624 Space(String),
625}
626
627#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
628#[serde(deny_unknown_fields, rename_all = "camelCase")]
629pub struct ListEnvironmentResourcesQuery {
630 #[serde(default, skip_serializing_if = "Option::is_none")]
631 pub owner_kind: Option<OwnerKind>,
632 #[serde(default, skip_serializing_if = "Option::is_none")]
633 pub owner_id: Option<String>,
634 #[serde(default, skip_serializing_if = "Vec::is_empty")]
636 pub contains_all: Vec<OwnerRef>,
637}
638
639#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
640#[serde(deny_unknown_fields, rename_all = "camelCase")]
641pub struct RevokeSpaceGrantRequest {
642 pub expected_version: u64,
643}
644
645#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
646#[serde(deny_unknown_fields, rename_all = "camelCase")]
647pub struct CreateSpaceGrantRequest {
648 pub principal: PrincipalRef,
649 pub capabilities: BTreeSet<SpaceCapability>,
650 #[serde(default)]
651 pub path_prefixes: Vec<String>,
652 #[serde(default, skip_serializing_if = "Option::is_none")]
653 pub expires_at_ms: Option<u64>,
654}
655
656#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
657#[serde(deny_unknown_fields, rename_all = "camelCase")]
658pub struct OpenSpaceSessionRequest {
659 pub mode: SpaceAccessMode,
660 #[serde(default, skip_serializing_if = "Option::is_none")]
661 pub delegation_id: Option<String>,
662 pub ttl_ms: u64,
663}
664
665#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
666#[serde(deny_unknown_fields, rename_all = "camelCase")]
667pub struct IssueSpaceAccessTicketRequest {
668 pub session_id: String,
669 pub ttl_ms: u64,
670}
671
672#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
673#[serde(deny_unknown_fields, rename_all = "camelCase")]
674pub struct AcquireSpaceWriteLeaseRequest {
675 pub session_id: String,
676 pub ttl_ms: u64,
677}
678
679#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
680#[serde(deny_unknown_fields, rename_all = "camelCase")]
681pub struct ReleaseSpaceWriteLeaseRequest {
682 pub session_id: String,
683 pub fencing_token: u64,
684}
685
686#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
687#[serde(deny_unknown_fields, rename_all = "camelCase")]
688pub struct HeartbeatSpaceSessionRequest {
689 pub ttl_ms: u64,
690}
691
692#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
693#[serde(deny_unknown_fields, rename_all = "camelCase")]
694pub struct CreateDelegationRequest {
695 pub delegate_agent_id: String,
696 #[serde(default)]
697 pub computer_ids: BTreeSet<String>,
698 #[serde(default)]
699 pub space_ids: BTreeSet<String>,
700 pub capabilities: BTreeSet<SpaceCapability>,
701 #[serde(default)]
702 pub path_prefixes: Vec<String>,
703 pub purpose: String,
704 pub expires_at_ms: u64,
705}
706
707#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
708#[serde(deny_unknown_fields, rename_all = "camelCase")]
709pub struct CreateTemplateVersionRequest {
710 pub template_id: String,
711 pub version: String,
712 pub provider: String,
713 #[serde(default, skip_serializing_if = "Option::is_none")]
714 pub provider_template_id: Option<String>,
715 pub target: TemplateTarget,
716 #[serde(default, skip_serializing_if = "Option::is_none")]
717 pub base_snapshot_id: Option<String>,
718 #[serde(default)]
719 pub resource_profile: BTreeMap<String, String>,
720 #[serde(default)]
721 pub parameter_schema: BTreeMap<String, String>,
722}
723
724#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
725#[serde(deny_unknown_fields, rename_all = "camelCase")]
726pub struct CreateSpaceChangeSetRequest {
727 pub source_space_id: String,
728 pub target_space_id: String,
729 pub created_by_session_id: String,
730}
731
732#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
733#[serde(deny_unknown_fields, rename_all = "camelCase")]
734pub struct ApplySpaceChangeSetRequest {
735 pub access_ticket_token: String,
736 pub fencing_token: u64,
737 pub expected_revision: u64,
738}
739
740#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
741#[serde(deny_unknown_fields, rename_all = "camelCase")]
742pub struct WriteSpaceFileRequest {
743 pub access_ticket_token: String,
744 pub fencing_token: u64,
745 pub expected_revision: u64,
746 #[serde(with = "base64_bytes")]
747 pub content: Vec<u8>,
748}
749
750#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
751#[serde(deny_unknown_fields, rename_all = "camelCase")]
752pub struct ReadSpaceFileRequest {
753 pub access_ticket_token: String,
754 pub path: String,
755}
756
757#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
758#[serde(deny_unknown_fields, rename_all = "camelCase")]
759pub struct ProviderFileContent {
760 pub bytes: Vec<u8>,
761 #[serde(default, skip_serializing_if = "Option::is_none")]
762 pub provider_revision: Option<String>,
763}
764
765#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
766#[serde(deny_unknown_fields, rename_all = "camelCase")]
767pub struct ProviderWriteResult {
768 #[serde(default, skip_serializing_if = "Option::is_none")]
769 pub provider_revision: Option<String>,
770}