1use std::collections::BTreeMap;
2
3use crate::{ai_catalog::ClientApi, Platform, ResourceType};
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use serde_json::Value as JsonValue;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
10#[serde(rename_all = "camelCase")]
11pub struct ResourceHeartbeat {
12 pub deployment_id: Option<String>,
13 pub resource_id: String,
16 pub resource_type: ResourceType,
17 pub controller_platform: Platform,
18 pub backend: HeartbeatBackend,
19 pub observed_at: DateTime<Utc>,
20 pub data: ResourceHeartbeatData,
21 pub raw: Vec<RawHeartbeatSnippet>,
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
26#[serde(rename_all = "camelCase")]
27pub struct ObservedInventoryBatch {
28 pub source_kind: String,
31 pub inventory_scope: String,
33 pub controller_platform: Platform,
35 pub backend: HeartbeatBackend,
37 pub observed_at: DateTime<Utc>,
39 pub complete: bool,
43 pub resources: Vec<ObservedResourceSample>,
44}
45
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
47#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
48#[serde(rename_all = "camelCase")]
49pub struct ObservedResourceSample {
50 pub deployment_id: Option<String>,
51 pub raw_identity: String,
54 pub provider_kind: String,
58 pub display_name: String,
59 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub namespace: Option<String>,
61 #[serde(default, skip_serializing_if = "Option::is_none")]
62 pub region: Option<String>,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub scope: Option<String>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
66 pub resource_type_hint: Option<ResourceType>,
67 #[serde(default, skip_serializing_if = "Option::is_none")]
69 pub version: Option<String>,
70 #[serde(default, skip_serializing_if = "Option::is_none")]
71 pub alien_resource_id: Option<String>,
72 pub health: ObservedHealth,
73 pub lifecycle: ProviderLifecycleState,
74 #[serde(default, skip_serializing_if = "Option::is_none")]
75 pub message: Option<String>,
76 pub partial: bool,
77 pub provider_stale: bool,
78 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub counts: Option<ObservedCounts>,
80 #[serde(default, skip_serializing_if = "Vec::is_empty")]
81 pub collection_issues: Vec<HeartbeatCollectionIssue>,
82 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
83 pub labels: BTreeMap<String, String>,
84 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
85 pub attributes: BTreeMap<String, JsonValue>,
86 #[serde(default, skip_serializing_if = "Vec::is_empty")]
87 pub raw: Vec<RawHeartbeatSnippet>,
88 #[serde(default, skip_serializing_if = "Vec::is_empty")]
91 pub images: Vec<ContainerImageIdentity>,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
96#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
97#[serde(rename_all = "camelCase")]
98pub struct ContainerImageIdentity {
99 pub name: String,
101 pub image: String,
103 #[serde(default, skip_serializing_if = "Option::is_none")]
106 pub digest: Option<String>,
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
110#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
111#[serde(rename_all = "camelCase")]
112pub enum HeartbeatBackend {
113 Aws,
114 Gcp,
115 Azure,
116 Kubernetes,
117 Local,
118 Managed,
119 External,
120 Test,
121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
124#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
125#[serde(rename_all = "kebab-case")]
126pub enum HeartbeatCollectionIssueReason {
127 Forbidden,
128 NotInstalled,
129 ApiUnavailable,
130 CollectionFailed,
131 TimedOut,
132}
133
134#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
135#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
136#[serde(tag = "resourceType", content = "data")]
137pub enum ResourceHeartbeatData {
138 #[serde(rename = "storage")]
139 Storage(StorageHeartbeatData),
140 #[serde(rename = "worker")]
141 Worker(WorkerHeartbeatData),
142 #[serde(rename = "container")]
143 Container(ContainerHeartbeatData),
144 #[serde(rename = "daemon")]
145 Daemon(DaemonHeartbeatData),
146 #[serde(rename = "compute-cluster")]
147 ComputeCluster(ComputeClusterHeartbeatData),
148 #[serde(rename = "kubernetes-cluster")]
149 KubernetesCluster(KubernetesClusterHeartbeatData),
150 #[serde(rename = "queue")]
151 Queue(QueueHeartbeatData),
152 #[serde(rename = "kv")]
153 Kv(KvHeartbeatData),
154 #[serde(rename = "postgres")]
155 Postgres(PostgresHeartbeatData),
156 #[serde(rename = "redis")]
157 Redis(RedisHeartbeatData),
158 #[serde(rename = "vault")]
159 Vault(VaultHeartbeatData),
160 #[serde(rename = "service-account")]
161 ServiceAccount(ServiceAccountHeartbeatData),
162 #[serde(rename = "network")]
163 Network(NetworkHeartbeatData),
164 #[serde(rename = "remote-stack-management")]
165 RemoteStackManagement(RemoteStackManagementHeartbeatData),
166 #[serde(rename = "artifact-registry")]
167 ArtifactRegistry(ArtifactRegistryHeartbeatData),
168 #[serde(rename = "build")]
169 Build(BuildHeartbeatData),
170 #[serde(rename = "service_activation")]
171 ServiceActivation(ServiceActivationHeartbeatData),
172 #[serde(rename = "azure_resource_group")]
173 AzureResourceGroup(AzureResourceGroupHeartbeatData),
174 #[serde(rename = "azure_storage_account")]
175 AzureStorageAccount(AzureStorageAccountHeartbeatData),
176 #[serde(rename = "azure_container_apps_environment")]
177 AzureContainerAppsEnvironment(AzureContainerAppsEnvironmentHeartbeatData),
178 #[serde(rename = "azure_service_bus_namespace")]
179 AzureServiceBusNamespace(AzureServiceBusNamespaceHeartbeatData),
180 #[serde(rename = "ai")]
181 Ai(AiHeartbeatData),
182 #[serde(rename = "key")]
183 Key(KeyHeartbeatData),
184 #[serde(rename = "sandbox")]
185 Sandbox(SandboxHeartbeatData),
186}
187
188#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
189#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
190#[serde(rename_all = "kebab-case")]
191pub enum ObservedHealth {
192 Unknown,
193 Healthy,
194 Degraded,
195 Unhealthy,
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
199#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
200#[serde(rename_all = "kebab-case")]
201pub enum ProviderLifecycleState {
202 Unknown,
203 Creating,
204 Updating,
205 Running,
206 Scaling,
207 Stopping,
208 Stopped,
209 Deleting,
210 Deleted,
211 Failed,
212}
213
214#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
215#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
216#[serde(rename_all = "camelCase")]
217pub struct KeyHeartbeatStatus {
218 pub health: ObservedHealth,
219 pub lifecycle: ProviderLifecycleState,
220 pub message: Option<String>,
221}
222
223#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
224#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
225#[serde(tag = "provider", content = "data", rename_all = "kebab-case")]
226pub enum KeyHeartbeatData {
227 AwsKms(AwsKmsKeyHeartbeatData),
228 GcpCloudKms(GcpCloudKmsKeyHeartbeatData),
229 AzureKeyVault(AzureKeyVaultKeyHeartbeatData),
230}
231
232#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
233#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
234#[serde(rename_all = "camelCase")]
235pub struct AwsKmsKeyHeartbeatData {
236 pub status: KeyHeartbeatStatus,
237 pub key_arn: String,
238 pub key_state: String,
239 pub enabled: bool,
240 pub key_spec: String,
241 pub key_usage: String,
242}
243
244#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
245#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
246#[serde(rename_all = "camelCase")]
247pub struct GcpCloudKmsKeyHeartbeatData {
248 pub status: KeyHeartbeatStatus,
249 pub crypto_key_name: String,
250 pub purpose: String,
251 pub primary_version: Option<String>,
252 pub primary_state: Option<String>,
253 pub algorithm: Option<String>,
254}
255
256#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
257#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
258#[serde(rename_all = "camelCase")]
259pub struct AzureKeyVaultKeyHeartbeatData {
260 pub status: KeyHeartbeatStatus,
261 pub key_id: String,
262 pub enabled: Option<bool>,
263 pub key_type: String,
264 pub key_operations: Vec<String>,
265 pub recovery_level: Option<String>,
266}
267
268#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
269#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
270#[serde(rename_all = "camelCase")]
271pub struct HeartbeatCollectionIssue {
272 pub source: String,
273 pub reason: HeartbeatCollectionIssueReason,
274 pub severity: HeartbeatIssueSeverity,
275 pub message: String,
276}
277
278#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
279#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
280#[serde(rename_all = "kebab-case")]
281pub enum HeartbeatIssueSeverity {
282 Info,
283 Warning,
284 Error,
285}
286
287#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
288#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
289#[serde(rename_all = "camelCase")]
290pub struct KubernetesEventSnapshot {
291 pub reason: String,
292 #[serde(rename = "type")]
293 pub type_: Option<String>,
294 pub message: String,
295 pub count: Option<i32>,
296 pub first_timestamp: Option<DateTime<Utc>>,
297 pub last_timestamp: Option<DateTime<Utc>>,
298 pub event_time: Option<DateTime<Utc>>,
299 pub source: Option<KubernetesEventSource>,
300 pub involved_object: Option<KubernetesEventInvolvedObject>,
301 pub raw: Option<JsonValue>,
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
305#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
306#[serde(rename_all = "camelCase")]
307pub struct KubernetesEventSource {
308 pub component: Option<String>,
309 pub host: Option<String>,
310}
311
312#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
313#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
314#[serde(rename_all = "camelCase")]
315pub struct KubernetesEventInvolvedObject {
316 pub kind: Option<String>,
317 pub namespace: Option<String>,
318 pub name: Option<String>,
319 pub uid: Option<String>,
320 pub api_version: Option<String>,
321 pub resource_version: Option<String>,
322 pub field_path: Option<String>,
323}
324
325#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
326#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
327#[serde(rename_all = "camelCase")]
328pub struct ManagedRuntimeEventSnapshot {
329 pub event_id: Option<String>,
330 pub reason: String,
331 #[serde(rename = "type")]
332 pub type_: Option<String>,
333 pub message: String,
334 pub count: Option<i32>,
335 pub first_timestamp: Option<DateTime<Utc>>,
336 pub last_timestamp: Option<DateTime<Utc>>,
337 pub event_time: Option<DateTime<Utc>>,
338 pub source: Option<ManagedRuntimeEventSource>,
339 pub involved_object: Option<ManagedRuntimeEventInvolvedObject>,
340 pub details: Option<JsonValue>,
341 pub raw: Option<JsonValue>,
342}
343
344#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
345#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
346#[serde(rename_all = "camelCase")]
347pub struct ManagedRuntimeEventSource {
348 pub component: Option<String>,
349 pub host: Option<String>,
350}
351
352#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
353#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
354#[serde(rename_all = "camelCase")]
355pub struct ManagedRuntimeEventInvolvedObject {
356 pub kind: Option<String>,
357 pub id: Option<String>,
358 pub name: Option<String>,
359 pub replica_id: Option<String>,
360 pub machine_id: Option<String>,
361 pub details: Option<JsonValue>,
362}
363
364#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
365#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
366#[serde(rename_all = "camelCase")]
367pub struct LocalRuntimeEventSnapshot {
368 pub timestamp: DateTime<Utc>,
369 pub severity: HeartbeatIssueSeverity,
370 pub kind: String,
371 pub message: String,
372 pub subject: Option<LocalRuntimeEventSubject>,
373 pub raw: Option<JsonValue>,
374}
375
376#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
377#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
378#[serde(rename_all = "camelCase")]
379pub struct LocalRuntimeEventSubject {
380 pub kind: String,
381 pub id: Option<String>,
382 pub name: Option<String>,
383}
384
385#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
386#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
387#[serde(rename_all = "camelCase")]
388pub struct RawHeartbeatSnippet {
389 pub source: String,
390 pub format: RawHeartbeatSnippetFormat,
391 pub collected_at: DateTime<Utc>,
392 pub body: String,
393 pub truncated: bool,
394}
395
396#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
397#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
398#[serde(rename_all = "kebab-case")]
399pub enum RawHeartbeatSnippetFormat {
400 Json,
401 Yaml,
402 Text,
403}
404
405#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
406#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
407#[serde(rename_all = "camelCase")]
408pub struct ObservedCounts {
409 pub desired: Option<u32>,
410 pub current: Option<u32>,
411 pub ready: Option<u32>,
412}
413
414#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
415#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
416#[serde(rename_all = "camelCase")]
417pub struct MetricSample {
418 pub value: f64,
419 pub unit: MetricUnit,
420}
421
422#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
423#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
424#[serde(rename_all = "kebab-case")]
425pub enum MetricUnit {
426 Count,
427 Percent,
428 Bytes,
429 Cores,
430 Milliseconds,
431 RequestsPerSecond,
432}
433
434#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
435#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
436#[serde(tag = "backend", rename_all = "camelCase")]
437pub enum StorageHeartbeatData {
438 AwsS3(AwsS3StorageHeartbeatData),
439 GcpCloudStorage(GcpCloudStorageHeartbeatData),
440 AzureBlob(AzureBlobStorageHeartbeatData),
441 Local(LocalStorageHeartbeatData),
442}
443
444#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
445#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
446#[serde(rename_all = "camelCase")]
447pub struct StorageHeartbeatStatus {
448 pub health: ObservedHealth,
449 pub lifecycle: ProviderLifecycleState,
450 pub message: Option<String>,
451 pub stale: bool,
452 pub partial: bool,
453 pub collection_issues: Vec<HeartbeatCollectionIssue>,
454}
455
456#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
457#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
458#[serde(rename_all = "camelCase")]
459pub struct AwsS3StorageHeartbeatData {
460 pub status: StorageHeartbeatStatus,
461 pub name: String,
462 pub region: Option<String>,
463 pub bucket_location: Option<String>,
464 pub versioning_status: Option<String>,
465 pub versioning_enabled: Option<bool>,
466 pub lifecycle_present: bool,
467 pub lifecycle_rule_count: Option<u64>,
468 pub encryption_config_present: bool,
469 pub encryption_enabled: Option<bool>,
470 pub public_access_block_present: bool,
471 pub block_public_acls: Option<bool>,
472 pub ignore_public_acls: Option<bool>,
473 pub block_public_policy: Option<bool>,
474 pub restrict_public_buckets: Option<bool>,
475 pub bucket_policy_present: Option<bool>,
476 pub bucket_acl_present: Option<bool>,
477}
478
479#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
480#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
481#[serde(rename_all = "camelCase")]
482pub struct AzureBlobStorageHeartbeatData {
483 pub status: StorageHeartbeatStatus,
484 pub name: String,
485 pub storage_account_name: Option<String>,
486 pub resource_group: Option<String>,
487 pub location: Option<String>,
488 pub account_kind: Option<String>,
489 pub sku_name: Option<String>,
490 pub sku_tier: Option<String>,
491 pub access_tier: Option<String>,
492 pub provisioning_state: Option<String>,
493 pub primary_location: Option<String>,
494 pub secondary_location: Option<String>,
495 pub status_of_primary: Option<String>,
496 pub status_of_secondary: Option<String>,
497 pub public_network_access: Option<String>,
498 pub allow_blob_public_access: Option<bool>,
499 pub encryption_key_source: Option<String>,
500 pub blob_encryption_enabled: Option<bool>,
501 pub file_encryption_enabled: Option<bool>,
502 pub queue_encryption_enabled: Option<bool>,
503 pub table_encryption_enabled: Option<bool>,
504 pub blob_versioning_enabled: Option<bool>,
505 pub blob_delete_retention_enabled: Option<bool>,
506 pub blob_delete_retention_days: Option<u64>,
507 pub container_delete_retention_enabled: Option<bool>,
508 pub container_delete_retention_days: Option<u64>,
509 pub change_feed_enabled: Option<bool>,
510 pub change_feed_retention_days: Option<u64>,
511 pub container_public_access: Option<String>,
512}
513
514#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
515#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
516#[serde(rename_all = "camelCase")]
517pub struct GcpCloudStorageHeartbeatData {
518 pub status: StorageHeartbeatStatus,
519 pub name: String,
520 pub bucket_id: Option<String>,
521 pub location: Option<String>,
522 pub location_type: Option<String>,
523 pub storage_class: Option<String>,
524 pub versioning_enabled: Option<bool>,
525 pub lifecycle_present: bool,
526 pub lifecycle_rule_count: Option<u64>,
527 pub retention_policy_effective_time: Option<String>,
528 pub retention_policy_is_locked: Option<bool>,
529 pub retention_period: Option<String>,
530 pub soft_delete_retention_duration_seconds: Option<String>,
531 pub soft_delete_effective_time: Option<String>,
532 pub uniform_bucket_level_access_enabled: Option<bool>,
533 pub uniform_bucket_level_access_locked_time: Option<String>,
534 pub public_access_prevention: Option<String>,
535 pub encryption_config_present: bool,
536 pub default_kms_key_name: Option<String>,
537}
538
539#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
540#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
541#[serde(rename_all = "camelCase")]
542pub struct LocalStorageHeartbeatData {
543 pub status: StorageHeartbeatStatus,
544 pub path: String,
545 pub path_exists: bool,
546 pub is_directory: Option<bool>,
547 pub readonly: Option<bool>,
548 pub modified_at: Option<DateTime<Utc>>,
549}
550
551#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
552#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
553#[serde(tag = "backend", rename_all = "camelCase")]
554pub enum WorkerHeartbeatData {
555 AwsLambda(AwsLambdaWorkerHeartbeatData),
556 GcpCloudRun(GcpCloudRunWorkerHeartbeatData),
557 AzureContainerApps(AzureContainerAppsWorkerHeartbeatData),
558 Kubernetes(KubernetesWorkerHeartbeatData),
559 Local(LocalWorkerHeartbeatData),
560}
561
562#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
563#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
564#[serde(tag = "backend", rename_all = "camelCase")]
565pub enum ContainerHeartbeatData {
566 HorizonPlatform(HorizonContainerHeartbeatData),
567 Kubernetes(KubernetesContainerHeartbeatData),
568 Local(LocalContainerHeartbeatData),
569}
570
571#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
572#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
573#[serde(tag = "backend", rename_all = "camelCase")]
574pub enum DaemonHeartbeatData {
575 Aws(AwsDaemonHeartbeatData),
576 Gcp(GcpDaemonHeartbeatData),
577 Azure(AzureDaemonHeartbeatData),
578 Machines(MachinesDaemonHeartbeatData),
579 Kubernetes(KubernetesDaemonHeartbeatData),
580 Local(LocalDaemonHeartbeatData),
581}
582
583#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
584#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
585#[serde(rename_all = "camelCase")]
586pub struct WorkloadHeartbeatStatus {
587 pub health: ObservedHealth,
588 pub lifecycle: ProviderLifecycleState,
589 pub message: Option<String>,
590 pub stale: bool,
591 pub partial: bool,
592 pub collection_issues: Vec<HeartbeatCollectionIssue>,
593}
594
595#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
596#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
597#[serde(rename_all = "camelCase")]
598pub struct WorkloadReplicaStatus {
599 pub desired: Option<u32>,
600 pub current: Option<u32>,
601 pub ready: Option<u32>,
602 pub available: Option<u32>,
603 pub updated: Option<u32>,
604 pub misscheduled: Option<u32>,
605}
606
607#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
608#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
609#[serde(rename_all = "camelCase")]
610pub struct AwsLambdaWorkerHeartbeatData {
611 pub status: WorkloadHeartbeatStatus,
612 pub function_name: String,
613 pub runtime: Option<String>,
614 pub package_type: Option<String>,
615 pub memory_size_mb: Option<i64>,
616 pub timeout_seconds: Option<i64>,
617 pub version: Option<String>,
618 pub revision_id: Option<String>,
619 pub last_modified: Option<String>,
620 pub state: Option<String>,
621 pub state_reason: Option<String>,
622 pub state_reason_code: Option<String>,
623 pub last_update_status: Option<String>,
624 pub last_update_status_reason: Option<String>,
625 pub last_update_status_reason_code: Option<String>,
626 pub code_sha256: Option<String>,
627 pub layer_count: u32,
628 pub function_url_auth_type: Option<String>,
629 pub function_url_cors_present: bool,
630 pub trigger_count: u32,
631}
632
633#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
634#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
635#[serde(rename_all = "camelCase")]
636pub struct GcpCloudRunWorkerHeartbeatData {
637 pub status: WorkloadHeartbeatStatus,
638 pub service: String,
639 pub region: Option<String>,
640 pub uri: Option<String>,
641 pub urls: Vec<String>,
642 pub latest_created_revision: Option<String>,
643 pub latest_ready_revision: Option<String>,
644 pub generation: Option<i64>,
645 pub observed_generation: Option<i64>,
646 pub traffic_count: u32,
647 pub min_instance_count: Option<i32>,
648 pub max_instance_count: Option<i32>,
649 pub container_image: Option<String>,
650 pub cpu_limit: Option<String>,
651 pub memory_limit: Option<String>,
652}
653
654#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
655#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
656#[serde(rename_all = "camelCase")]
657pub struct AzureContainerAppsWorkerHeartbeatData {
658 pub status: WorkloadHeartbeatStatus,
659 pub app_name: String,
660 pub revision: Option<String>,
661 pub environment_name: Option<String>,
662 pub provisioning_state: Option<String>,
663 pub running_status: Option<String>,
664 pub ingress_fqdn: Option<String>,
665 pub min_replicas: Option<i32>,
666 pub max_replicas: Option<i32>,
667 pub cpu: Option<f64>,
668 pub memory: Option<String>,
669}
670
671#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
672#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
673#[serde(rename_all = "camelCase")]
674pub struct KubernetesWorkerHeartbeatData {
675 pub status: WorkloadHeartbeatStatus,
676 pub namespace: String,
677 pub name: String,
678 pub workload_kind: KubernetesWorkloadKind,
679 pub replicas: WorkloadReplicaStatus,
680 pub restarts: Option<u32>,
681 pub cpu: Option<MetricSample>,
682 pub memory: Option<MetricSample>,
683 pub workload: Option<KubernetesWorkloadStatus>,
684 pub pods: Vec<KubernetesPodRuntimeUnitStatus>,
685 pub trigger_count: u32,
686 pub events: Vec<KubernetesEventSnapshot>,
687}
688
689#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
690#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
691#[serde(rename_all = "camelCase")]
692pub struct LocalWorkerHeartbeatData {
693 pub status: WorkloadHeartbeatStatus,
694 pub pid: Option<u32>,
695 pub command_supported: bool,
696 pub image_path_present: bool,
697 pub readiness_probe_ok: Option<bool>,
698 pub trigger_count: u32,
699 pub cpu: Option<MetricSample>,
700 pub memory: Option<MetricSample>,
701 pub process: Option<LocalRuntimeUnitStatus>,
702 pub events: Vec<LocalRuntimeEventSnapshot>,
703}
704
705#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
706#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
707#[serde(rename_all = "camelCase")]
708pub struct HorizonContainerHeartbeatData {
709 pub status: WorkloadHeartbeatStatus,
710 pub container_id: String,
711 pub image: Option<String>,
712 #[serde(default)]
713 pub observed_image: Option<String>,
714 #[serde(default)]
715 pub latest_update_timestamp: Option<String>,
716 pub scheduling_mode: HorizonWorkloadSchedulingMode,
717 pub replicas: WorkloadReplicaStatus,
718 pub cpu: Option<MetricSample>,
719 pub memory: Option<MetricSample>,
720 pub attention_count: u32,
721 pub replica_units: Vec<ManagedRuntimeUnitStatus>,
722 pub events: Vec<ManagedRuntimeEventSnapshot>,
723}
724
725#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
726#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
727#[serde(rename_all = "camelCase")]
728pub enum HorizonWorkloadSchedulingMode {
729 Replicated,
730 Stateful,
731 Daemon,
732}
733
734#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
735#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
736#[serde(rename_all = "camelCase")]
737pub struct KubernetesContainerHeartbeatData {
738 pub status: WorkloadHeartbeatStatus,
739 pub namespace: String,
740 pub name: String,
741 pub workload_kind: KubernetesWorkloadKind,
742 pub replicas: WorkloadReplicaStatus,
743 pub restarts: Option<u32>,
744 pub cpu: Option<MetricSample>,
745 pub memory: Option<MetricSample>,
746 pub workload: Option<KubernetesWorkloadStatus>,
747 pub pods: Vec<KubernetesPodRuntimeUnitStatus>,
748 pub events: Vec<KubernetesEventSnapshot>,
749}
750
751#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
752#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
753#[serde(rename_all = "camelCase")]
754pub struct LocalContainerHeartbeatData {
755 pub status: WorkloadHeartbeatStatus,
756 pub container_id: Option<String>,
757 pub name: Option<String>,
758 pub image: Option<String>,
759 pub runtime_status: Option<String>,
760 pub restart_count: Option<u32>,
761 pub port_count: u32,
762 pub bind_mount_count: u32,
763 pub local_url: Option<String>,
764 pub runtime_reachable: bool,
765 pub cpu: Option<MetricSample>,
766 pub memory: Option<MetricSample>,
767 pub container_unit: Option<LocalRuntimeUnitStatus>,
768 pub events: Vec<LocalRuntimeEventSnapshot>,
769}
770
771#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
772#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
773#[serde(rename_all = "camelCase")]
774pub struct AwsDaemonHeartbeatData {
775 pub status: WorkloadHeartbeatStatus,
776 pub horizon_cluster_id: String,
777 #[serde(default)]
778 pub daemon_name: String,
779 pub horizon_status: String,
780 pub horizon_status_reason: Option<String>,
781 pub horizon_status_message: Option<String>,
782 pub capacity_group: String,
783 pub desired_machines: u32,
784 pub assigned_machines: u32,
785 pub healthy_instances: u32,
786 pub unavailable_instances: u32,
787 pub command_supported: bool,
788 #[serde(default)]
789 pub observed_image: Option<String>,
790 pub latest_update_timestamp: String,
791 pub daemon_instances: Vec<ManagedRuntimeUnitStatus>,
792 pub events: Vec<ManagedRuntimeEventSnapshot>,
793}
794
795#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
796#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
797#[serde(rename_all = "camelCase")]
798pub struct GcpDaemonHeartbeatData {
799 pub status: WorkloadHeartbeatStatus,
800 pub horizon_cluster_id: String,
801 #[serde(default)]
802 pub daemon_name: String,
803 pub horizon_status: String,
804 pub horizon_status_reason: Option<String>,
805 pub horizon_status_message: Option<String>,
806 pub capacity_group: String,
807 pub desired_machines: u32,
808 pub assigned_machines: u32,
809 pub healthy_instances: u32,
810 pub unavailable_instances: u32,
811 pub command_supported: bool,
812 #[serde(default)]
813 pub observed_image: Option<String>,
814 pub latest_update_timestamp: String,
815 pub daemon_instances: Vec<ManagedRuntimeUnitStatus>,
816 pub events: Vec<ManagedRuntimeEventSnapshot>,
817}
818
819#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
820#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
821#[serde(rename_all = "camelCase")]
822pub struct AzureDaemonHeartbeatData {
823 pub status: WorkloadHeartbeatStatus,
824 pub horizon_cluster_id: String,
825 #[serde(default)]
826 pub daemon_name: String,
827 pub horizon_status: String,
828 pub horizon_status_reason: Option<String>,
829 pub horizon_status_message: Option<String>,
830 pub capacity_group: String,
831 pub desired_machines: u32,
832 pub assigned_machines: u32,
833 pub healthy_instances: u32,
834 pub unavailable_instances: u32,
835 pub command_supported: bool,
836 #[serde(default)]
837 pub observed_image: Option<String>,
838 pub latest_update_timestamp: String,
839 pub daemon_instances: Vec<ManagedRuntimeUnitStatus>,
840 pub events: Vec<ManagedRuntimeEventSnapshot>,
841}
842
843#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
844#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
845#[serde(rename_all = "camelCase")]
846pub struct MachinesDaemonHeartbeatData {
847 pub status: WorkloadHeartbeatStatus,
848 pub horizon_cluster_id: String,
849 #[serde(default)]
850 pub daemon_name: String,
851 pub horizon_status: String,
852 pub horizon_status_reason: Option<String>,
853 pub horizon_status_message: Option<String>,
854 pub capacity_group: String,
855 pub desired_machines: u32,
856 pub assigned_machines: u32,
857 pub healthy_instances: u32,
858 pub unavailable_instances: u32,
859 pub command_supported: bool,
860 #[serde(default)]
861 pub observed_image: Option<String>,
862 pub latest_update_timestamp: String,
863 pub daemon_instances: Vec<ManagedRuntimeUnitStatus>,
864 pub events: Vec<ManagedRuntimeEventSnapshot>,
865}
866
867#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
868#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
869#[serde(rename_all = "camelCase")]
870pub struct ManagedRuntimeUnitStatus {
871 pub replica_id: String,
872 pub name: String,
873 pub machine_id: Option<String>,
874 pub node_name: Option<String>,
875 pub ip: Option<String>,
876 pub ready: bool,
877 pub phase: Option<String>,
878 pub status: Option<String>,
879 pub reason: Option<String>,
880 pub message: Option<String>,
881 pub restart_count: Option<u32>,
882 pub waiting_reason: Option<String>,
883 pub terminated_reason: Option<String>,
884 pub metrics_healthy: Option<bool>,
885 pub metrics_status: Option<String>,
886 pub metrics_last_updated: Option<String>,
887 pub cpu: Option<MetricSample>,
888 pub memory: Option<MetricSample>,
889 #[serde(default)]
891 pub image: Option<String>,
892}
893
894#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
895#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
896#[serde(rename_all = "camelCase")]
897pub struct KubernetesDaemonHeartbeatData {
898 pub status: WorkloadHeartbeatStatus,
899 pub namespace: String,
900 pub name: String,
901 pub replicas: WorkloadReplicaStatus,
902 pub restarts: Option<u32>,
903 pub command_supported: bool,
904 pub cpu: Option<MetricSample>,
905 pub memory: Option<MetricSample>,
906 pub workload: Option<KubernetesWorkloadStatus>,
907 pub pods: Vec<KubernetesPodRuntimeUnitStatus>,
908 pub events: Vec<KubernetesEventSnapshot>,
909}
910
911#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
912#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
913#[serde(rename_all = "camelCase")]
914pub struct LocalDaemonHeartbeatData {
915 pub status: WorkloadHeartbeatStatus,
916 #[serde(default)]
917 pub daemon_name: String,
918 pub runtime_id: String,
919 pub pid: Option<u32>,
920 pub command_supported: bool,
921 pub image_path_present: bool,
922 pub restart_count: Option<u32>,
923 pub exit_reason: Option<String>,
924 pub daemon_instance: Option<LocalRuntimeUnitStatus>,
925 pub events: Vec<LocalRuntimeEventSnapshot>,
926}
927
928#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
929#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
930#[serde(rename_all = "camelCase")]
931pub struct LocalRuntimeUnitStatus {
932 pub unit_id: String,
933 pub name: String,
934 pub kind: LocalRuntimeUnitKind,
935 pub ready: bool,
936 pub phase: Option<String>,
937 pub pid: Option<u32>,
938 pub restart_count: Option<u32>,
939 pub cpu: Option<MetricSample>,
940 pub memory: Option<MetricSample>,
941}
942
943#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
944#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
945#[serde(rename_all = "kebab-case")]
946pub enum LocalRuntimeUnitKind {
947 Container,
948 Process,
949 Daemon,
950}
951
952#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
953#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
954#[serde(rename_all = "camelCase")]
955pub enum KubernetesWorkloadKind {
956 Deployment,
957 StatefulSet,
958 DaemonSet,
959 ReplicaSet,
960 Pod,
961}
962
963#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
964#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
965#[serde(rename_all = "camelCase")]
966pub struct KubernetesWorkloadStatus {
967 pub desired_replicas: Option<u32>,
968 pub ready_replicas: Option<u32>,
969 pub available_replicas: Option<u32>,
970 pub updated_replicas: Option<u32>,
971 pub observed_generation: Option<i64>,
972 pub desired_generation: Option<i64>,
973 pub rollout_reason: Option<String>,
974 pub conditions: Vec<KubernetesWorkloadCondition>,
975}
976
977#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
978#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
979#[serde(rename_all = "camelCase")]
980pub struct KubernetesWorkloadCondition {
981 #[serde(rename = "type")]
982 pub condition_type: String,
983 pub status: String,
984 pub reason: Option<String>,
985 pub message: Option<String>,
986 pub last_transition_time: Option<DateTime<Utc>>,
987}
988
989#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
990#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
991#[serde(rename_all = "camelCase")]
992pub struct KubernetesPodRuntimeUnitStatus {
993 pub name: String,
994 pub uid: Option<String>,
995 pub phase: Option<String>,
996 pub ready: bool,
997 pub restart_count: u32,
998 pub waiting_reason: Option<String>,
999 pub terminated_reason: Option<String>,
1000 pub node_name: Option<String>,
1001 pub pod_ip: Option<String>,
1002 pub owner_references: Vec<KubernetesOwnerReference>,
1003 pub cpu: Option<MetricSample>,
1004 pub memory: Option<MetricSample>,
1005 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1006 pub containers: Vec<ContainerImageIdentity>,
1007}
1008
1009#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1010#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1011#[serde(rename_all = "camelCase")]
1012pub struct KubernetesOwnerReference {
1013 pub kind: String,
1014 pub name: String,
1015 pub uid: String,
1016 pub controller: bool,
1017}
1018
1019#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1020#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1021#[serde(tag = "backend", rename_all = "camelCase")]
1022pub enum ComputeClusterHeartbeatData {
1023 Aws(AwsComputeClusterHeartbeatData),
1024 Gcp(GcpComputeClusterHeartbeatData),
1025 Azure(AzureComputeClusterHeartbeatData),
1026 Machines(MachinesComputeClusterHeartbeatData),
1027 Local(LocalComputeClusterHeartbeatData),
1028}
1029
1030#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1031#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1032#[serde(rename_all = "camelCase")]
1033pub struct ComputeClusterHeartbeatStatus {
1034 pub health: ObservedHealth,
1035 pub lifecycle: ProviderLifecycleState,
1036 pub message: Option<String>,
1037 pub stale: bool,
1038 pub partial: bool,
1039 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1040}
1041
1042#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1043#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1044#[serde(rename_all = "camelCase")]
1045pub struct LocalComputeClusterHeartbeatData {
1046 pub status: ComputeClusterHeartbeatStatus,
1047 pub nodes: ObservedCounts,
1048 pub name: String,
1049 pub host_identifier: Option<String>,
1050 pub docker_available: bool,
1051 pub docker_version: Option<String>,
1052 pub docker_api_version: Option<String>,
1053 pub docker_os: Option<String>,
1054 pub docker_arch: Option<String>,
1055 pub network_name: Option<String>,
1056 pub network_available: bool,
1057 pub tracked_containers: Option<u32>,
1058 pub running_containers: Option<u32>,
1059}
1060
1061#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1062#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1063#[serde(rename_all = "camelCase")]
1064pub struct AwsComputeClusterHeartbeatData {
1065 pub status: ComputeClusterHeartbeatStatus,
1066 pub nodes: ObservedCounts,
1067 pub cpu: Option<MetricSample>,
1068 pub memory: Option<MetricSample>,
1069 pub name: String,
1070 pub region: Option<String>,
1071 pub backend_cluster_id: Option<String>,
1072 pub capacity_groups: Vec<ComputeCapacityGroupStatus>,
1073 pub provider_fleets: Vec<ProviderFleetStatus>,
1074}
1075
1076#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1077#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1078#[serde(rename_all = "camelCase")]
1079pub struct GcpComputeClusterHeartbeatData {
1080 pub status: ComputeClusterHeartbeatStatus,
1081 pub nodes: ObservedCounts,
1082 pub cpu: Option<MetricSample>,
1083 pub memory: Option<MetricSample>,
1084 pub name: String,
1085 pub region: Option<String>,
1086 pub backend_cluster_id: Option<String>,
1087 pub capacity_groups: Vec<ComputeCapacityGroupStatus>,
1088 pub provider_fleets: Vec<ProviderFleetStatus>,
1089}
1090
1091#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1092#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1093#[serde(rename_all = "camelCase")]
1094pub struct AzureComputeClusterHeartbeatData {
1095 pub status: ComputeClusterHeartbeatStatus,
1096 pub nodes: ObservedCounts,
1097 pub cpu: Option<MetricSample>,
1098 pub memory: Option<MetricSample>,
1099 pub name: String,
1100 pub region: Option<String>,
1101 pub backend_cluster_id: Option<String>,
1102 pub capacity_groups: Vec<ComputeCapacityGroupStatus>,
1103 pub provider_fleets: Vec<ProviderFleetStatus>,
1104}
1105
1106#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1107#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1108#[serde(rename_all = "camelCase")]
1109pub struct MachinesComputeClusterHeartbeatData {
1110 pub status: ComputeClusterHeartbeatStatus,
1111 pub nodes: ObservedCounts,
1112 pub cpu: Option<MetricSample>,
1113 pub memory: Option<MetricSample>,
1114 pub name: String,
1115 pub backend_cluster_id: Option<String>,
1116 pub capacity_groups: Vec<ComputeCapacityGroupStatus>,
1117 pub machines: Vec<MachinesComputeMachineStatus>,
1118}
1119
1120#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1121#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1122#[serde(rename_all = "camelCase")]
1123pub struct MachinesComputeMachineStatus {
1124 pub machine_id: String,
1125 pub status: String,
1126 pub capacity_group: String,
1127 pub zone: String,
1128 pub public_ip: Option<String>,
1129 pub overlay_ip: Option<String>,
1130 pub last_heartbeat: String,
1131 pub horizond_version: Option<String>,
1132 pub replica_count: i64,
1133 pub cpu_cores: Option<f64>,
1134 pub memory_bytes: Option<i64>,
1135 pub drain_force: bool,
1136 pub drain_requested_at: Option<String>,
1137 pub drain_deadline_at: Option<String>,
1138 pub drained_at: Option<String>,
1139 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1140 pub drain_blockers: Vec<ComputeDrainBlocker>,
1141}
1142
1143#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1144#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1145#[serde(rename_all = "camelCase")]
1146pub struct ComputeCapacityGroupStatus {
1147 pub group_id: String,
1148 pub current_machines: u32,
1149 pub desired_machines: u32,
1150 pub min_machines: Option<u32>,
1151 pub max_machines: Option<u32>,
1152 pub instance_type: Option<String>,
1153 pub recommendation: Option<ComputeCapacityRecommendation>,
1154 pub capacity_blocker: Option<ComputeCapacityBlocker>,
1155 #[serde(default, skip_serializing_if = "Option::is_none")]
1156 pub drain_progress: Option<ComputeDrainProgress>,
1157}
1158
1159#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1160#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1161#[serde(rename_all = "camelCase")]
1162pub enum ComputeCapacityBlockerCategory {
1163 Quota,
1164 Capacity,
1165 Allocation,
1166 Other,
1167}
1168
1169#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1170#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1171#[serde(rename_all = "camelCase")]
1172pub struct ComputeCapacityBlocker {
1173 pub category: ComputeCapacityBlockerCategory,
1174 pub provider_code: Option<String>,
1175 pub message: String,
1176 pub provider_reference: Option<String>,
1177 pub observed_at: DateTime<Utc>,
1178}
1179
1180#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1181#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1182#[serde(rename_all = "camelCase")]
1183pub struct ComputeCapacityRecommendation {
1184 pub desired_machines: u32,
1185 pub reason: Option<String>,
1186 pub utilization: Option<MetricSample>,
1187 pub unschedulable_replicas: Option<u32>,
1188}
1189
1190#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1191#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1192#[serde(rename_all = "camelCase")]
1193pub enum ComputeDrainProgressStatus {
1194 Draining,
1195 Drained,
1196 Terminating,
1197}
1198
1199#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1200#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1201#[serde(rename_all = "camelCase")]
1202pub struct ComputeDrainBlocker {
1203 pub workload_name: String,
1204 pub replica_id: String,
1205 pub scheduling_mode: String,
1206 pub state: String,
1207 pub reason: String,
1208}
1209
1210#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1211#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1212#[serde(rename_all = "camelCase")]
1213pub struct ComputeDrainProgress {
1214 pub machine_id: String,
1215 pub status: ComputeDrainProgressStatus,
1216 pub replica_count: i64,
1217 pub force: bool,
1218 pub stalled: bool,
1219 pub drain_requested_at: Option<String>,
1220 pub drain_deadline_at: Option<String>,
1221 pub drained_at: Option<String>,
1222 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1223 pub blockers: Vec<ComputeDrainBlocker>,
1224}
1225
1226#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1227#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1228#[serde(rename_all = "camelCase")]
1229pub struct ProviderFleetStatus {
1230 pub group_id: String,
1231 pub provider_id: String,
1232 pub location: Option<String>,
1233 pub current_machines: u32,
1234 pub desired_machines: u32,
1235}
1236
1237#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1238#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1239#[serde(rename_all = "camelCase")]
1240pub struct KubernetesClusterHeartbeatData {
1241 pub status: WorkloadHeartbeatStatus,
1242 pub node_counts: ObservedCounts,
1243 pub pod_counts: ObservedCounts,
1244 pub cpu: Option<MetricSample>,
1245 pub memory: Option<MetricSample>,
1246 pub name: String,
1247 pub region: Option<String>,
1248 pub namespace: Option<String>,
1249 pub version: Option<String>,
1250 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1251 pub node_statuses: Vec<KubernetesClusterNodeStatus>,
1252 pub events: Vec<KubernetesEventSnapshot>,
1253}
1254
1255#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1256#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1257#[serde(rename_all = "camelCase")]
1258pub struct KubernetesClusterNodeStatus {
1259 pub name: String,
1260 pub uid: Option<String>,
1261 pub ready: bool,
1262 #[serde(default, skip_serializing_if = "Vec::is_empty")]
1263 pub conditions: Vec<KubernetesNodeConditionStatus>,
1264 pub roles: Vec<String>,
1265 pub labels: BTreeMap<String, String>,
1266 pub allocatable: KubernetesNodeResources,
1267 pub capacity: KubernetesNodeResources,
1268 pub usage: Option<KubernetesNodeUsage>,
1269 pub kubelet_version: Option<String>,
1270 pub container_runtime_version: Option<String>,
1271}
1272
1273#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1274#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1275#[serde(rename_all = "camelCase")]
1276pub struct KubernetesNodeConditionStatus {
1277 pub type_: String,
1278 pub status: String,
1279 pub reason: Option<String>,
1280 pub message: Option<String>,
1281}
1282
1283#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1284#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1285#[serde(rename_all = "camelCase")]
1286pub struct KubernetesNodeResources {
1287 pub cpu: Option<MetricSample>,
1288 pub memory: Option<MetricSample>,
1289 pub pods: Option<u64>,
1290}
1291
1292#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1293#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1294#[serde(rename_all = "camelCase")]
1295pub struct KubernetesNodeUsage {
1296 pub cpu: Option<MetricSample>,
1297 pub memory: Option<MetricSample>,
1298}
1299
1300#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1301#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1302#[serde(tag = "backend", rename_all = "camelCase")]
1303pub enum QueueHeartbeatData {
1304 AwsSqs(AwsSqsQueueHeartbeatData),
1305 GcpPubSub(GcpPubSubQueueHeartbeatData),
1306 AzureServiceBus(AzureServiceBusQueueHeartbeatData),
1307 Local(LocalQueueHeartbeatData),
1308}
1309
1310#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1311#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1312#[serde(rename_all = "camelCase")]
1313pub struct QueueHeartbeatStatus {
1314 pub health: ObservedHealth,
1315 pub lifecycle: ProviderLifecycleState,
1316 pub message: Option<String>,
1317 pub stale: bool,
1318 pub partial: bool,
1319 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1320}
1321
1322impl Default for QueueHeartbeatStatus {
1323 fn default() -> Self {
1324 Self {
1325 health: ObservedHealth::Unknown,
1326 lifecycle: ProviderLifecycleState::Unknown,
1327 message: None,
1328 stale: false,
1329 partial: false,
1330 collection_issues: vec![],
1331 }
1332 }
1333}
1334
1335#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1336#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1337#[serde(rename_all = "camelCase")]
1338pub struct LocalQueueHeartbeatData {
1339 pub status: QueueHeartbeatStatus,
1340 pub name: String,
1341 pub path: Option<String>,
1342 pub service_status: Option<String>,
1343}
1344
1345#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1346#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1347#[serde(rename_all = "camelCase")]
1348pub struct GcpPubSubQueueHeartbeatData {
1349 pub status: QueueHeartbeatStatus,
1350 pub topic_name: String,
1351 pub subscription_name: Option<String>,
1352 pub project_id: Option<String>,
1353 pub topic_full_name: Option<String>,
1354 pub subscription_full_name: Option<String>,
1355 pub endpoint: Option<String>,
1356 pub topic_labels: BTreeMap<String, String>,
1357 pub subscription_labels: BTreeMap<String, String>,
1358 pub message_storage_allowed_persistence_regions: Vec<String>,
1359 pub message_storage_enforce_in_transit: Option<bool>,
1360 pub kms_key_name: Option<String>,
1361 pub schema_name: Option<String>,
1362 pub schema_encoding: Option<String>,
1363 pub schema_first_revision_id: Option<String>,
1364 pub schema_last_revision_id: Option<String>,
1365 pub topic_message_retention_duration: Option<String>,
1366 pub topic_state: Option<String>,
1367 pub subscription_ack_deadline_seconds: Option<u32>,
1368 pub subscription_message_retention_duration: Option<String>,
1369 pub subscription_retain_acked_messages: Option<bool>,
1370 pub subscription_enable_message_ordering: Option<bool>,
1371 pub subscription_filter: Option<String>,
1372 pub subscription_detached: Option<bool>,
1373 pub subscription_state: Option<String>,
1374 pub subscription_push_config_present: Option<bool>,
1375 pub subscription_push_endpoint: Option<String>,
1376 pub subscription_push_attributes: BTreeMap<String, String>,
1377 pub subscription_push_oidc_service_account_email: Option<String>,
1378 pub subscription_push_oidc_audience: Option<String>,
1379 pub subscription_push_pubsub_wrapper_write_metadata: Option<bool>,
1380 pub subscription_push_no_wrapper_write_metadata: Option<bool>,
1381 pub subscription_dead_letter_topic: Option<String>,
1382 pub subscription_dead_letter_max_delivery_attempts: Option<u32>,
1383}
1384
1385#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1386#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1387#[serde(rename_all = "camelCase")]
1388pub struct AzureServiceBusQueueHeartbeatData {
1389 pub status: QueueHeartbeatStatus,
1390 pub name: String,
1391 pub namespace_name: String,
1392 pub resource_group: Option<String>,
1393 pub resource_id: Option<String>,
1394 pub endpoint: Option<String>,
1395 pub queue_status: Option<String>,
1396 pub lock_duration: Option<String>,
1397 pub max_delivery_count: Option<u32>,
1398 pub requires_duplicate_detection: Option<bool>,
1399 pub duplicate_detection_history_time_window: Option<String>,
1400 pub requires_session: Option<bool>,
1401 pub dead_lettering_on_message_expiration: Option<bool>,
1402 pub forward_dead_lettered_messages_to: Option<String>,
1403 pub forward_to: Option<String>,
1404 pub default_message_time_to_live: Option<String>,
1405 pub auto_delete_on_idle: Option<String>,
1406 pub enable_batched_operations: Option<bool>,
1407 pub enable_express: Option<bool>,
1408 pub enable_partitioning: Option<bool>,
1409 pub max_message_size_in_kilobytes: Option<u64>,
1410 pub max_size_in_megabytes: Option<u32>,
1411 pub message_count: Option<u64>,
1412 pub active_message_count: Option<u64>,
1413 pub dead_letter_message_count: Option<u64>,
1414 pub scheduled_message_count: Option<u64>,
1415 pub transfer_message_count: Option<u64>,
1416 pub transfer_dead_letter_message_count: Option<u64>,
1417 pub size_in_bytes: Option<u64>,
1418 pub accessed_at: Option<String>,
1419 pub created_at: Option<String>,
1420 pub updated_at: Option<String>,
1421}
1422
1423#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1424#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1425#[serde(rename_all = "camelCase")]
1426pub struct AwsSqsQueueHeartbeatData {
1427 pub status: QueueHeartbeatStatus,
1428 pub name: String,
1429 pub region: Option<String>,
1430 pub queue_url: Option<String>,
1431 pub queue_arn: Option<String>,
1432 pub visibility_timeout_seconds: Option<u32>,
1433 pub message_retention_period_seconds: Option<u32>,
1434 pub delay_seconds: Option<u32>,
1435 pub receive_message_wait_time_seconds: Option<u32>,
1436 pub maximum_message_size: Option<u32>,
1437 pub redrive_policy: Option<String>,
1438 pub redrive_allow_policy: Option<String>,
1439 pub fifo_queue: Option<bool>,
1440 pub content_based_deduplication: Option<bool>,
1441 pub deduplication_scope: Option<String>,
1442 pub fifo_throughput_limit: Option<String>,
1443 pub sse_enabled: Option<bool>,
1444 pub kms_master_key_id: Option<String>,
1445 pub kms_data_key_reuse_period_seconds: Option<u32>,
1446 pub sqs_managed_sse_enabled: Option<bool>,
1447 pub approximate_visible_messages: Option<u64>,
1448 pub approximate_in_flight_messages: Option<u64>,
1449 pub approximate_delayed_messages: Option<u64>,
1450 pub approximate_counts: bool,
1451}
1452
1453#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1454#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1455#[serde(tag = "backend", rename_all = "camelCase")]
1456pub enum KvHeartbeatData {
1457 AwsDynamoDb(AwsDynamoDbKvHeartbeatData),
1458 GcpFirestore(GcpFirestoreKvHeartbeatData),
1459 AzureTable(AzureTableKvHeartbeatData),
1460 Local(LocalKvHeartbeatData),
1461}
1462
1463#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1464#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1465#[serde(rename_all = "camelCase")]
1466pub struct KvHeartbeatStatus {
1467 pub health: ObservedHealth,
1468 pub lifecycle: ProviderLifecycleState,
1469 pub message: Option<String>,
1470 pub stale: bool,
1471 pub partial: bool,
1472 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1473}
1474
1475impl Default for KvHeartbeatStatus {
1476 fn default() -> Self {
1477 Self {
1478 health: ObservedHealth::Unknown,
1479 lifecycle: ProviderLifecycleState::Unknown,
1480 message: None,
1481 stale: false,
1482 partial: false,
1483 collection_issues: vec![],
1484 }
1485 }
1486}
1487
1488#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1489#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1490#[serde(rename_all = "camelCase")]
1491pub struct AwsDynamoDbKvHeartbeatData {
1492 pub status: KvHeartbeatStatus,
1493 pub name: String,
1494 pub region: Option<String>,
1495 pub table_arn: Option<String>,
1496 pub table_status: Option<String>,
1497 pub billing_mode: Option<String>,
1498 pub key_schema: Vec<AwsDynamoDbKeySchemaElement>,
1499 pub global_secondary_index_count: Option<u32>,
1500 pub local_secondary_index_count: Option<u32>,
1501 pub item_count: Option<u64>,
1502 pub table_size_bytes: Option<u64>,
1503 pub stream_enabled: Option<bool>,
1504 pub stream_view_type: Option<String>,
1505 pub ttl_status: Option<String>,
1506 pub ttl_attribute_name: Option<String>,
1507 pub deletion_protection_enabled: Option<bool>,
1508 pub sse_status: Option<String>,
1509 pub sse_type: Option<String>,
1510 pub table_class: Option<String>,
1511 pub replica_count: Option<u32>,
1512 pub restore_in_progress: Option<bool>,
1513}
1514
1515#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1516#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1517#[serde(rename_all = "camelCase")]
1518pub struct AwsDynamoDbKeySchemaElement {
1519 pub attribute_name: String,
1520 pub key_type: String,
1521}
1522
1523#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1524#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1525#[serde(rename_all = "camelCase")]
1526pub struct GcpFirestoreKvHeartbeatData {
1527 pub status: KvHeartbeatStatus,
1528 pub database_name: String,
1529 pub project_id: Option<String>,
1530 pub endpoint: Option<String>,
1531 pub location_id: Option<String>,
1532 pub database_type: Option<String>,
1533 pub concurrency_mode: Option<String>,
1534 pub app_engine_integration_mode: Option<String>,
1535 pub delete_protection_state: Option<String>,
1536 pub point_in_time_recovery_enablement: Option<String>,
1537 pub version_retention_period: Option<String>,
1538 pub earliest_version_time: Option<String>,
1539 pub create_time: Option<String>,
1540 pub update_time: Option<String>,
1541 pub delete_time: Option<String>,
1542 pub database_edition: Option<String>,
1543 pub cmek_enabled: bool,
1544 pub source_info_present: bool,
1545}
1546
1547#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1548#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1549#[serde(rename_all = "camelCase")]
1550pub struct AzureTableKvHeartbeatData {
1551 pub status: KvHeartbeatStatus,
1552 pub table_name: String,
1553 pub storage_account_name: String,
1554 pub resource_group: Option<String>,
1555 pub endpoint: Option<String>,
1556 pub storage_account_resource_id: Option<String>,
1557 pub storage_account_location: Option<String>,
1558 pub storage_account_kind: Option<String>,
1559 pub storage_account_provisioning_state: Option<String>,
1560 pub storage_account_primary_status: Option<String>,
1561 pub table_exists: bool,
1562 pub signed_identifier_count: Option<u32>,
1563}
1564
1565#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1566#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1567#[serde(rename_all = "camelCase")]
1568pub struct LocalKvHeartbeatData {
1569 pub status: KvHeartbeatStatus,
1570 pub name: String,
1571 pub path: String,
1572 pub path_exists: bool,
1573 pub is_directory: Option<bool>,
1574 pub cloud_metadata_supported: bool,
1575}
1576
1577#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1578#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1579#[serde(tag = "backend", rename_all = "camelCase")]
1580pub enum PostgresHeartbeatData {
1581 Aurora(AuroraPostgresHeartbeatData),
1583 CloudSql(GcpCloudSqlPostgresHeartbeatData),
1585 FlexibleServer(AzureFlexibleServerPostgresHeartbeatData),
1587 Local(LocalPostgresHeartbeatData),
1589}
1590
1591#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1592#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1593#[serde(rename_all = "camelCase")]
1594pub struct PostgresHeartbeatStatus {
1595 pub health: ObservedHealth,
1596 pub lifecycle: ProviderLifecycleState,
1597 pub message: Option<String>,
1598 pub stale: bool,
1599 pub partial: bool,
1600 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1601}
1602
1603impl Default for PostgresHeartbeatStatus {
1604 fn default() -> Self {
1605 Self {
1606 health: ObservedHealth::Unknown,
1607 lifecycle: ProviderLifecycleState::Unknown,
1608 message: None,
1609 stale: false,
1610 partial: false,
1611 collection_issues: vec![],
1612 }
1613 }
1614}
1615
1616#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1619#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1620#[serde(tag = "backend", rename_all = "camelCase")]
1621pub enum RedisHeartbeatData {
1622 Elasticache(ElasticacheRedisHeartbeatData),
1624 Memorystore(MemorystoreRedisHeartbeatData),
1626 AzureManagedRedis(AzureManagedRedisHeartbeatData),
1628 Local(LocalRedisHeartbeatData),
1630}
1631
1632#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1634#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1635#[serde(rename_all = "camelCase")]
1636pub struct RedisHeartbeatStatus {
1637 pub health: ObservedHealth,
1638 pub lifecycle: ProviderLifecycleState,
1639 pub message: Option<String>,
1640 pub stale: bool,
1641 pub partial: bool,
1642 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1643}
1644
1645impl Default for RedisHeartbeatStatus {
1646 fn default() -> Self {
1647 Self {
1648 health: ObservedHealth::Unknown,
1649 lifecycle: ProviderLifecycleState::Unknown,
1650 message: None,
1651 stale: false,
1652 partial: false,
1653 collection_issues: vec![],
1654 }
1655 }
1656}
1657
1658#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
1661#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1662#[serde(rename_all = "camelCase")]
1663pub struct RedisMetricsSample {
1664 #[serde(skip_serializing_if = "Option::is_none")]
1666 pub memory_used_percent: Option<f64>,
1667 #[serde(skip_serializing_if = "Option::is_none")]
1669 pub evictions: Option<f64>,
1670 #[serde(skip_serializing_if = "Option::is_none")]
1672 pub connected_clients: Option<f64>,
1673 #[serde(skip_serializing_if = "Option::is_none")]
1675 pub replication_lag_seconds: Option<f64>,
1676}
1677
1678#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
1681#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1682#[serde(rename_all = "camelCase")]
1683pub struct RedisObservedConfig {
1684 #[serde(skip_serializing_if = "Option::is_none")]
1686 pub engine_version: Option<String>,
1687 #[serde(skip_serializing_if = "Option::is_none")]
1689 pub node_type: Option<String>,
1690 #[serde(skip_serializing_if = "Option::is_none")]
1691 pub endpoint: Option<String>,
1692 #[serde(skip_serializing_if = "Option::is_none")]
1693 pub port: Option<u16>,
1694 #[serde(skip_serializing_if = "Option::is_none")]
1695 pub eviction_policy: Option<String>,
1696 #[serde(skip_serializing_if = "Option::is_none")]
1697 pub persistence_enabled: Option<bool>,
1698 #[serde(skip_serializing_if = "Option::is_none")]
1700 pub replica_count: Option<u32>,
1701 #[serde(skip_serializing_if = "Option::is_none")]
1702 pub tls_enabled: Option<bool>,
1703 #[serde(skip_serializing_if = "Option::is_none")]
1704 pub auth_enabled: Option<bool>,
1705 #[serde(skip_serializing_if = "Option::is_none")]
1707 pub public_network_access: Option<bool>,
1708}
1709
1710#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1711#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1712#[serde(rename_all = "camelCase")]
1713pub struct ElasticacheRedisHeartbeatData {
1714 pub status: RedisHeartbeatStatus,
1715 pub replication_group_id: String,
1716 #[serde(skip_serializing_if = "Option::is_none")]
1717 pub state: Option<String>,
1718 pub config: RedisObservedConfig,
1719 pub metrics: RedisMetricsSample,
1720}
1721
1722#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1723#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1724#[serde(rename_all = "camelCase")]
1725pub struct MemorystoreRedisHeartbeatData {
1726 pub status: RedisHeartbeatStatus,
1727 pub instance_name: String,
1728 #[serde(skip_serializing_if = "Option::is_none")]
1729 pub state: Option<String>,
1730 pub config: RedisObservedConfig,
1731 pub metrics: RedisMetricsSample,
1732}
1733
1734#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1735#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1736#[serde(rename_all = "camelCase")]
1737pub struct AzureManagedRedisHeartbeatData {
1738 pub status: RedisHeartbeatStatus,
1739 pub cluster_name: String,
1740 #[serde(skip_serializing_if = "Option::is_none")]
1741 pub state: Option<String>,
1742 pub config: RedisObservedConfig,
1743 pub metrics: RedisMetricsSample,
1744}
1745
1746#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1747#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1748#[serde(rename_all = "camelCase")]
1749pub struct LocalRedisHeartbeatData {
1750 pub status: RedisHeartbeatStatus,
1751 pub name: String,
1752 pub port: Option<u16>,
1753 pub version: String,
1754 pub process_running: bool,
1755}
1756
1757#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1762#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1763#[serde(tag = "backend", rename_all = "camelCase")]
1764pub enum SandboxHeartbeatData {
1765 AwsMicrovm(AwsMicrovmSandboxHeartbeatData),
1766 AzureSandboxGroup(AzureSandboxGroupHeartbeatData),
1767 GcpAgentPlatform(GcpAgentPlatformSandboxHeartbeatData),
1768 KubernetesPods(KubernetesSandboxHeartbeatData),
1769 Local(LocalSandboxHeartbeatData),
1770}
1771
1772#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1773#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1774#[serde(rename_all = "camelCase")]
1775pub struct SandboxHeartbeatStatus {
1776 pub health: ObservedHealth,
1777 pub lifecycle: ProviderLifecycleState,
1778 pub message: Option<String>,
1779 pub stale: bool,
1780 pub partial: bool,
1781 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1782}
1783
1784impl Default for SandboxHeartbeatStatus {
1785 fn default() -> Self {
1786 Self {
1787 health: ObservedHealth::Healthy,
1788 lifecycle: ProviderLifecycleState::Running,
1789 message: None,
1790 stale: false,
1791 partial: false,
1792 collection_issues: Vec::new(),
1793 }
1794 }
1795}
1796
1797#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1799#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1800#[serde(rename_all = "camelCase")]
1801pub struct AwsMicrovmSandboxHeartbeatData {
1802 pub status: SandboxHeartbeatStatus,
1803 pub image_identifier: String,
1805 pub image_state: Option<String>,
1812}
1813
1814#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1817#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1818#[serde(rename_all = "camelCase")]
1819pub struct AzureSandboxGroupHeartbeatData {
1820 pub status: SandboxHeartbeatStatus,
1821 pub sandbox_group: String,
1822 pub provisioning_state: Option<String>,
1823}
1824
1825#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1831#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1832#[serde(rename_all = "camelCase")]
1833pub struct GcpAgentPlatformSandboxHeartbeatData {
1834 pub status: SandboxHeartbeatStatus,
1835 pub engine: String,
1837 pub template_id: String,
1839}
1840
1841#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1843#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1844#[serde(rename_all = "camelCase")]
1845pub struct KubernetesSandboxHeartbeatData {
1846 pub status: SandboxHeartbeatStatus,
1847 pub namespace: String,
1848 pub active_sessions: u32,
1849 pub idle_pods: u32,
1851}
1852
1853#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1855#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1856#[serde(rename_all = "camelCase")]
1857pub struct LocalSandboxHeartbeatData {
1858 pub status: SandboxHeartbeatStatus,
1859 pub active_sessions: u32,
1860 pub route_serving: bool,
1863}
1864
1865#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1866#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1867#[serde(tag = "backend", rename_all = "camelCase")]
1868pub enum AiHeartbeatData {
1869 AwsBedrock(AwsBedrockAiHeartbeatData),
1870 GcpVertex(GcpVertexAiHeartbeatData),
1871 AzureFoundry(AzureFoundryAiHeartbeatData),
1872 External(ExternalAiHeartbeatData),
1873}
1874
1875#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1876#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1877#[serde(rename_all = "camelCase")]
1878pub struct AiHeartbeatStatus {
1879 pub health: ObservedHealth,
1880 pub lifecycle: ProviderLifecycleState,
1881 pub message: Option<String>,
1882 pub stale: bool,
1883 pub partial: bool,
1884 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1885}
1886
1887impl Default for AiHeartbeatStatus {
1888 fn default() -> Self {
1889 Self {
1891 health: ObservedHealth::Unknown,
1892 lifecycle: ProviderLifecycleState::Unknown,
1893 message: None,
1894 stale: false,
1895 partial: false,
1896 collection_issues: vec![],
1897 }
1898 }
1899}
1900
1901#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1904#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1905#[serde(rename_all = "kebab-case")]
1906pub enum AiAvailabilitySource {
1907 AwsBedrock,
1908 GcpVertex,
1909 AzureFoundry,
1910 Anthropic,
1911}
1912
1913#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1914#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1915#[serde(rename_all = "kebab-case")]
1916pub enum AiModelAvailability {
1917 Available,
1918 Blocked,
1919 Unknown,
1920}
1921
1922#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1923#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1924#[serde(rename_all = "kebab-case")]
1925pub enum AiAvailabilityBlocker {
1926 AgreementRequired,
1927 EntitlementRequired,
1928 ModelActivationRequired,
1929 DeploymentRequired,
1930 QuotaConfigurationRequired,
1931 RegionUnavailable,
1932 AccessDenied,
1933 ObservationFailed,
1934}
1935
1936#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1937#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1938#[serde(rename_all = "kebab-case")]
1939pub enum AiAccessTest {
1940 Verified,
1941 Failed,
1942 NotChecked,
1943}
1944
1945#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1946#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1947#[serde(rename_all = "camelCase")]
1948pub struct AiModelAvailabilityObservation {
1949 pub public_model_id: String,
1950 pub client_apis: Vec<ClientApi>,
1951 pub availability: AiModelAvailability,
1952 pub blockers: Vec<AiAvailabilityBlocker>,
1953 pub access_test: AiAccessTest,
1954 #[serde(skip_serializing_if = "Option::is_none")]
1955 pub tested_at: Option<DateTime<Utc>>,
1956 #[serde(skip_serializing_if = "Option::is_none")]
1957 pub error_code: Option<String>,
1958}
1959
1960#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1961#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1962#[serde(rename_all = "camelCase")]
1963pub struct AiAvailabilityObservation {
1964 pub source: AiAvailabilitySource,
1965 pub catalog_revision: String,
1966 #[serde(skip_serializing_if = "Option::is_none")]
1967 pub location: Option<String>,
1968 pub models: Vec<AiModelAvailabilityObservation>,
1969}
1970
1971impl AiAvailabilityObservation {
1972 pub fn unobserved(
1975 source: AiAvailabilitySource,
1976 platform: Platform,
1977 location: Option<String>,
1978 ) -> Self {
1979 Self {
1980 source,
1981 catalog_revision: crate::ai_catalog::AI_CATALOG_REVISION.to_string(),
1982 location,
1983 models: crate::ai_catalog::models_for(platform)
1984 .into_iter()
1985 .map(|model| AiModelAvailabilityObservation {
1986 public_model_id: model.public_id.to_string(),
1987 client_apis: ClientApi::ALL.to_vec(),
1988 availability: AiModelAvailability::Unknown,
1989 blockers: vec![AiAvailabilityBlocker::ObservationFailed],
1990 access_test: AiAccessTest::NotChecked,
1991 tested_at: None,
1992 error_code: None,
1993 })
1994 .collect(),
1995 }
1996 }
1997}
1998
1999#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2000#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2001#[serde(rename_all = "camelCase")]
2002pub struct LocalPostgresHeartbeatData {
2003 pub status: PostgresHeartbeatStatus,
2004 pub name: String,
2005 pub port: Option<u16>,
2006 pub version: String,
2007 pub process_running: bool,
2008}
2009
2010#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2011#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2012#[serde(rename_all = "camelCase")]
2013pub struct AuroraPostgresHeartbeatData {
2014 pub status: PostgresHeartbeatStatus,
2015 pub cluster_identifier: String,
2016 #[serde(skip_serializing_if = "Option::is_none")]
2017 pub engine_version: Option<String>,
2018 #[serde(skip_serializing_if = "Option::is_none")]
2019 pub endpoint: Option<String>,
2020 #[serde(skip_serializing_if = "Option::is_none")]
2022 pub serverless_capacity: Option<f64>,
2023 pub never_pauses: bool,
2026}
2027
2028#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2029#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2030#[serde(rename_all = "camelCase")]
2031pub struct GcpCloudSqlPostgresHeartbeatData {
2032 pub status: PostgresHeartbeatStatus,
2033 pub instance_name: String,
2034 #[serde(skip_serializing_if = "Option::is_none")]
2035 pub state: Option<String>,
2036 #[serde(skip_serializing_if = "Option::is_none")]
2037 pub database_version: Option<String>,
2038}
2039
2040#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2041#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2042#[serde(rename_all = "camelCase")]
2043pub struct AzureFlexibleServerPostgresHeartbeatData {
2044 pub status: PostgresHeartbeatStatus,
2045 pub server_name: String,
2046 #[serde(skip_serializing_if = "Option::is_none")]
2047 pub state: Option<String>,
2048 #[serde(skip_serializing_if = "Option::is_none")]
2049 pub version: Option<String>,
2050}
2051
2052#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2053#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2054#[serde(rename_all = "camelCase")]
2055pub struct AwsBedrockAiHeartbeatData {
2056 pub status: AiHeartbeatStatus,
2057 pub region: String,
2058 pub availability: AiAvailabilityObservation,
2059}
2060
2061#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2062#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2063#[serde(rename_all = "camelCase")]
2064pub struct GcpVertexAiHeartbeatData {
2065 pub status: AiHeartbeatStatus,
2066 pub project: String,
2067 pub location: String,
2068 pub availability: AiAvailabilityObservation,
2069}
2070
2071#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2072#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2073#[serde(rename_all = "camelCase")]
2074pub struct AzureFoundryAiHeartbeatData {
2075 pub status: AiHeartbeatStatus,
2076 pub account_name: String,
2077 pub endpoint: Option<String>,
2078 pub resource_group: Option<String>,
2079 pub location: Option<String>,
2080 pub availability: AiAvailabilityObservation,
2081}
2082
2083#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2084#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2085#[serde(rename_all = "camelCase")]
2086pub struct ExternalAiHeartbeatData {
2087 pub status: AiHeartbeatStatus,
2088 pub provider: String,
2091 #[serde(skip_serializing_if = "Option::is_none")]
2092 pub availability: Option<AiAvailabilityObservation>,
2093}
2094
2095#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2096#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2097#[serde(tag = "backend", rename_all = "camelCase")]
2098pub enum VaultHeartbeatData {
2099 AwsParameterStore(AwsParameterStoreVaultHeartbeatData),
2100 GcpSecretManager(GcpSecretManagerVaultHeartbeatData),
2101 AzureKeyVault(AzureKeyVaultHeartbeatData),
2102 KubernetesSecret(KubernetesSecretVaultHeartbeatData),
2103 Local(LocalVaultHeartbeatData),
2104}
2105
2106#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2107#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2108#[serde(rename_all = "camelCase")]
2109pub struct VaultHeartbeatStatus {
2110 pub health: ObservedHealth,
2111 pub lifecycle: ProviderLifecycleState,
2112 pub message: Option<String>,
2113 pub stale: bool,
2114 pub partial: bool,
2115 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2116}
2117
2118impl Default for VaultHeartbeatStatus {
2119 fn default() -> Self {
2120 Self {
2121 health: ObservedHealth::Healthy,
2122 lifecycle: ProviderLifecycleState::Running,
2123 message: None,
2124 stale: false,
2125 partial: false,
2126 collection_issues: vec![],
2127 }
2128 }
2129}
2130
2131#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2132#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2133#[serde(rename_all = "camelCase")]
2134pub struct AwsParameterStoreVaultHeartbeatData {
2135 pub status: VaultHeartbeatStatus,
2136 pub account_id: String,
2137 pub region: String,
2138 pub prefix: String,
2139 pub parameter_metadata_sampled: bool,
2140 pub sampled_parameter_count: Option<u32>,
2141 pub sampled_secure_string_count: Option<u32>,
2142 pub sampled_string_count: Option<u32>,
2143 pub sampled_string_list_count: Option<u32>,
2144 pub sampled_advanced_tier_count: Option<u32>,
2145 pub sampled_kms_key_metadata_present_count: Option<u32>,
2146 pub latest_modified_at: Option<DateTime<Utc>>,
2147 pub has_more_parameters: Option<bool>,
2148}
2149
2150#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2151#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2152#[serde(rename_all = "camelCase")]
2153pub struct GcpSecretManagerVaultHeartbeatData {
2154 pub status: VaultHeartbeatStatus,
2155 pub project_id: String,
2156 pub location: String,
2157 pub prefix: String,
2158 pub secret_metadata_listed: bool,
2159}
2160
2161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2162#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2163#[serde(rename_all = "camelCase")]
2164pub struct AzureKeyVaultHeartbeatData {
2165 pub status: VaultHeartbeatStatus,
2166 pub name: String,
2167 pub resource_group: Option<String>,
2168 pub resource_id: Option<String>,
2169 pub location: Option<String>,
2170 pub vault_uri: Option<String>,
2171 pub provisioning_state: Option<String>,
2172 pub sku_family: Option<String>,
2173 pub sku_name: Option<String>,
2174 pub soft_delete_enabled: bool,
2175 pub soft_delete_retention_days: i32,
2176 pub purge_protection_enabled: Option<bool>,
2177 pub rbac_authorization_enabled: bool,
2178 pub public_network_access: String,
2179 pub access_policy_count: u32,
2180 pub private_endpoint_connection_count: u32,
2181 pub secret_metadata_listed: bool,
2182}
2183
2184#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2185#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2186#[serde(rename_all = "camelCase")]
2187pub struct KubernetesSecretVaultHeartbeatData {
2188 pub status: VaultHeartbeatStatus,
2189 pub namespace: String,
2190 pub prefix: String,
2191 pub secret_metadata_listed: bool,
2192}
2193
2194#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2195#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2196#[serde(rename_all = "camelCase")]
2197pub struct LocalVaultHeartbeatData {
2198 pub status: VaultHeartbeatStatus,
2199 pub path: String,
2200 pub path_exists: bool,
2201 pub is_directory: Option<bool>,
2202 pub readonly: Option<bool>,
2203 pub modified_at: Option<DateTime<Utc>>,
2204 pub secret_metadata_listed: bool,
2205}
2206
2207#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2208#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2209#[serde(tag = "backend", rename_all = "camelCase")]
2210pub enum ServiceAccountHeartbeatData {
2211 AwsIamRole(AwsIamRoleServiceAccountHeartbeatData),
2212 GcpServiceAccount(GcpServiceAccountHeartbeatData),
2213 AzureManagedIdentity(AzureManagedIdentityServiceAccountHeartbeatData),
2214 Local(LocalServiceAccountHeartbeatData),
2215}
2216
2217#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2218#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2219#[serde(rename_all = "camelCase")]
2220pub struct ServiceAccountHeartbeatStatus {
2221 pub health: ObservedHealth,
2222 pub lifecycle: ProviderLifecycleState,
2223 pub message: Option<String>,
2224 pub stale: bool,
2225 pub partial: bool,
2226 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2227}
2228
2229#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2230#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2231#[serde(rename_all = "camelCase")]
2232pub struct AwsIamRoleServiceAccountHeartbeatData {
2233 pub status: ServiceAccountHeartbeatStatus,
2234 pub role_name: String,
2235 pub role_arn: String,
2236 pub role_id: String,
2237 pub path: String,
2238 pub create_date: String,
2239 pub description: Option<String>,
2240 pub max_session_duration: Option<i32>,
2241 pub assume_role_policy_present: bool,
2242 pub permissions_boundary_type: Option<String>,
2243 pub permissions_boundary_arn: Option<String>,
2244 pub tag_count: u32,
2245 pub managed_tag_count: u32,
2246 pub attached_policy_count: u32,
2247 pub attached_policy_names: Vec<String>,
2248 pub inline_policy_count: u32,
2249 pub inline_policy_names: Vec<String>,
2250 pub stack_permissions_applied: bool,
2251 pub last_used_date: Option<String>,
2252 pub last_used_region: Option<String>,
2253}
2254
2255#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2256#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2257#[serde(rename_all = "camelCase")]
2258pub struct GcpServiceAccountHeartbeatData {
2259 pub status: ServiceAccountHeartbeatStatus,
2260 pub name: Option<String>,
2261 pub project_id: Option<String>,
2262 pub unique_id: Option<String>,
2263 pub email: String,
2264 pub display_name: Option<String>,
2265 pub description: Option<String>,
2266 pub oauth2_client_id: Option<String>,
2267 pub disabled: Option<bool>,
2268 pub etag: Option<String>,
2269 pub project_binding_count: u32,
2270 pub project_roles: Vec<String>,
2271 pub service_account_binding_count: u32,
2272 pub service_account_roles: Vec<String>,
2273}
2274
2275#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2276#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2277#[serde(rename_all = "camelCase")]
2278pub struct AzureManagedIdentityServiceAccountHeartbeatData {
2279 pub status: ServiceAccountHeartbeatStatus,
2280 pub name: String,
2281 pub resource_id: String,
2282 pub resource_group: String,
2283 pub location: String,
2284 pub type_: Option<String>,
2285 pub client_id: Option<String>,
2286 pub principal_id: Option<String>,
2287 pub tenant_id: Option<String>,
2288 pub isolation_scope: Option<String>,
2289 pub managed_tag_count: u32,
2290 pub role_assignment_count: u32,
2291 pub role_assignment_ids: Vec<String>,
2292 pub custom_role_definition_count: u32,
2293 pub custom_role_definition_ids: Vec<String>,
2294 pub stack_permissions_applied: bool,
2295}
2296
2297#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2298#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2299#[serde(rename_all = "camelCase")]
2300pub struct LocalServiceAccountHeartbeatData {
2301 pub status: ServiceAccountHeartbeatStatus,
2302 pub identity: String,
2303 pub configured: bool,
2304}
2305
2306#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2307#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2308#[serde(tag = "backend", rename_all = "camelCase")]
2309pub enum NetworkHeartbeatData {
2310 AwsVpc(AwsVpcNetworkHeartbeatData),
2311 GcpVpc(GcpVpcNetworkHeartbeatData),
2312 AzureVnet(AzureVnetNetworkHeartbeatData),
2313}
2314
2315#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2316#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2317#[serde(rename_all = "camelCase")]
2318pub struct NetworkHeartbeatStatus {
2319 pub health: ObservedHealth,
2320 pub lifecycle: ProviderLifecycleState,
2321 pub message: Option<String>,
2322 pub stale: bool,
2323 pub partial: bool,
2324 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2325}
2326
2327#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2328#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2329#[serde(rename_all = "camelCase")]
2330pub struct AwsVpcNetworkHeartbeatData {
2331 pub status: NetworkHeartbeatStatus,
2332 pub vpc_id: Option<String>,
2333 pub vpc_state: Option<String>,
2334 pub cidr_block: Option<String>,
2335 pub public_subnet_ids: Vec<String>,
2336 pub private_subnet_ids: Vec<String>,
2337 pub availability_zones: Vec<String>,
2338 pub internet_gateway_id: Option<String>,
2339 pub nat_gateway_id: Option<String>,
2340 pub route_table_count: u32,
2341 pub security_group_id: Option<String>,
2342 pub is_byo_vpc: bool,
2343}
2344
2345#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2346#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2347#[serde(rename_all = "camelCase")]
2348pub struct GcpVpcNetworkHeartbeatData {
2349 pub status: NetworkHeartbeatStatus,
2350 pub network_name: Option<String>,
2351 pub network_self_link: Option<String>,
2352 pub subnetwork_name: Option<String>,
2353 pub subnetwork_self_link: Option<String>,
2354 pub region: Option<String>,
2355 pub cidr_block: Option<String>,
2356 pub router_name: Option<String>,
2357 pub cloud_nat_name: Option<String>,
2358 pub firewall_name: Option<String>,
2359 pub is_byo_vpc: bool,
2360}
2361
2362#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2363#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2364#[serde(rename_all = "camelCase")]
2365pub struct AzureVnetNetworkHeartbeatData {
2366 pub status: NetworkHeartbeatStatus,
2367 pub vnet_name: Option<String>,
2368 pub vnet_resource_id: Option<String>,
2369 pub resource_group: Option<String>,
2370 pub location: Option<String>,
2371 pub cidr_block: Option<String>,
2372 pub public_subnet_name: Option<String>,
2373 pub private_subnet_name: Option<String>,
2374 pub application_gateway_subnet_name: Option<String>,
2375 pub private_endpoint_subnet_name: Option<String>,
2376 pub nat_gateway_id: Option<String>,
2377 pub public_ip_id: Option<String>,
2378 pub nsg_id: Option<String>,
2379 pub is_byo_vnet: bool,
2380 pub last_byo_vnet_verification_error_code: Option<String>,
2381}
2382
2383#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2384#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2385#[serde(tag = "backend", rename_all = "camelCase")]
2386pub enum RemoteStackManagementHeartbeatData {
2387 AwsIamRole(AwsRemoteStackManagementHeartbeatData),
2388 GcpServiceAccount(GcpRemoteStackManagementHeartbeatData),
2389 AzureManagedIdentity(AzureRemoteStackManagementHeartbeatData),
2390}
2391
2392#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2393#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2394#[serde(rename_all = "camelCase")]
2395pub struct RemoteStackManagementHeartbeatStatus {
2396 pub health: ObservedHealth,
2397 pub lifecycle: ProviderLifecycleState,
2398 pub message: Option<String>,
2399 pub stale: bool,
2400 pub partial: bool,
2401 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2402}
2403
2404#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2405#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2406#[serde(rename_all = "camelCase")]
2407pub struct AwsRemoteStackManagementHeartbeatData {
2408 pub status: RemoteStackManagementHeartbeatStatus,
2409 pub role_name: Option<String>,
2410 pub role_arn: Option<String>,
2411 pub management_permissions_applied: bool,
2412}
2413
2414#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2415#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2416#[serde(rename_all = "camelCase")]
2417pub struct GcpRemoteStackManagementHeartbeatData {
2418 pub status: RemoteStackManagementHeartbeatStatus,
2419 pub service_account_email: Option<String>,
2420 pub service_account_unique_id: Option<String>,
2421 pub role_bound: bool,
2422 pub impersonation_granted: bool,
2423}
2424
2425#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2426#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2427#[serde(rename_all = "camelCase")]
2428pub struct AzureRemoteStackManagementHeartbeatData {
2429 pub status: RemoteStackManagementHeartbeatStatus,
2430 pub uami_resource_id: Option<String>,
2431 pub uami_client_id: Option<String>,
2432 pub uami_principal_id: Option<String>,
2433 pub tenant_id: Option<String>,
2434 pub fic_name: Option<String>,
2435 pub role_definition_id: Option<String>,
2436 pub role_assignment_ids: Vec<String>,
2437}
2438
2439#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2440#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2441#[serde(tag = "backend", rename_all = "camelCase")]
2442pub enum ArtifactRegistryHeartbeatData {
2443 AwsEcr(AwsEcrArtifactRegistryHeartbeatData),
2444 GcpArtifactRegistry(GcpArtifactRegistryHeartbeatData),
2445 AzureContainerRegistry(AzureContainerRegistryHeartbeatData),
2446 Local(LocalArtifactRegistryHeartbeatData),
2447}
2448
2449#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2450#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2451#[serde(rename_all = "camelCase")]
2452pub struct ArtifactRegistryHeartbeatStatus {
2453 pub health: ObservedHealth,
2454 pub lifecycle: ProviderLifecycleState,
2455 pub message: Option<String>,
2456 pub stale: bool,
2457 pub partial: bool,
2458 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2459}
2460
2461#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2462#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2463#[serde(rename_all = "camelCase")]
2464pub struct AwsEcrArtifactRegistryHeartbeatData {
2465 pub status: ArtifactRegistryHeartbeatStatus,
2466 pub registry_id: String,
2467 pub region: String,
2468 pub registry_uri: String,
2469 pub repository_prefix: String,
2470 pub pull_role_arn: Option<String>,
2471 pub push_role_arn: Option<String>,
2472 pub repository_count: u32,
2473 pub repositories_truncated: bool,
2474 pub repositories: Vec<AwsEcrRepositoryHeartbeatData>,
2475}
2476
2477#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2478#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2479#[serde(rename_all = "camelCase")]
2480pub struct AwsEcrRepositoryHeartbeatData {
2481 pub repository_arn: String,
2482 pub registry_id: String,
2483 pub repository_name: String,
2484 pub repository_uri: String,
2485 pub created_at: f64,
2486 pub image_tag_mutability: Option<String>,
2487 pub scan_on_push: Option<bool>,
2488 pub encryption_type: Option<String>,
2489 pub kms_key_present: bool,
2490}
2491
2492#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2493#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2494#[serde(rename_all = "camelCase")]
2495pub struct GcpArtifactRegistryHeartbeatData {
2496 pub status: ArtifactRegistryHeartbeatStatus,
2497 pub project_id: String,
2498 pub location: String,
2499 pub repository_id: String,
2500 pub name: Option<String>,
2501 pub format: Option<String>,
2502 pub mode: Option<String>,
2503 pub description: Option<String>,
2504 pub label_count: u32,
2505 pub cleanup_policy_count: u32,
2506 pub cleanup_policy_dry_run: Option<bool>,
2507 pub kms_key_name_present: bool,
2508 pub size_bytes: Option<String>,
2509 pub satisfies_pzs: Option<bool>,
2510 pub create_time: Option<String>,
2511 pub update_time: Option<String>,
2512 pub iam_policy_etag_present: bool,
2513 pub iam_binding_count: u32,
2514 pub iam_roles: Vec<String>,
2515 pub pull_service_account_email: Option<String>,
2516 pub push_service_account_email: Option<String>,
2517}
2518
2519#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2520#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2521#[serde(rename_all = "camelCase")]
2522pub struct AzureContainerRegistryHeartbeatData {
2523 pub status: ArtifactRegistryHeartbeatStatus,
2524 pub name: String,
2525 pub resource_id: Option<String>,
2526 pub resource_group: String,
2527 pub location: String,
2528 pub type_: Option<String>,
2529 pub login_server: Option<String>,
2530 pub sku_name: String,
2531 pub sku_tier: Option<String>,
2532 pub provisioning_state: Option<String>,
2533 pub admin_user_enabled: bool,
2534 pub anonymous_pull_enabled: bool,
2535 pub public_network_access: String,
2536 pub network_rule_bypass_options: String,
2537 pub network_rule_default_action: Option<String>,
2538 pub ip_rule_count: u32,
2539 pub encryption_status: Option<String>,
2540 pub encryption_key_vault_uri_present: bool,
2541 pub encryption_key_identifier_present: bool,
2542 pub policies_present: bool,
2543 pub policy_count: u32,
2544 pub private_endpoint_connection_count: u32,
2545 pub data_endpoint_enabled: Option<bool>,
2546 pub data_endpoint_host_names: Vec<String>,
2547 pub zone_redundancy: String,
2548 pub creation_date: Option<String>,
2549 pub managed_tag_count: u32,
2550}
2551
2552#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2553#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2554#[serde(rename_all = "camelCase")]
2555pub struct LocalArtifactRegistryHeartbeatData {
2556 pub status: ArtifactRegistryHeartbeatStatus,
2557 pub registry_url: String,
2558 pub reachable: bool,
2559}
2560
2561#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2562#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2563#[serde(tag = "backend", rename_all = "camelCase")]
2564pub enum BuildHeartbeatData {
2565 AwsCodeBuild(AwsCodeBuildHeartbeatData),
2566 GcpCloudBuild(GcpCloudBuildHeartbeatData),
2567 AzureContainerApps(AzureContainerAppsBuildHeartbeatData),
2568 KubernetesJob(KubernetesBuildHeartbeatData),
2569}
2570
2571#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2572#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2573#[serde(rename_all = "camelCase")]
2574pub struct BuildHeartbeatStatus {
2575 pub health: ObservedHealth,
2576 pub lifecycle: ProviderLifecycleState,
2577 pub message: Option<String>,
2578 pub stale: bool,
2579 pub partial: bool,
2580 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2581}
2582
2583#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2584#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2585#[serde(rename_all = "camelCase")]
2586pub struct AwsCodeBuildHeartbeatData {
2587 pub status: BuildHeartbeatStatus,
2588 pub project_name: String,
2589 pub project_arn: Option<String>,
2590 pub description: Option<String>,
2591 pub source_type: Option<String>,
2592 pub artifacts_type: Option<String>,
2593 pub artifacts_encryption_disabled: Option<bool>,
2594 pub environment_type: Option<String>,
2595 pub environment_image: Option<String>,
2596 pub compute_type: Option<String>,
2597 pub image_pull_credentials_type: Option<String>,
2598 pub privileged_mode: Option<bool>,
2599 pub environment_variable_count: u32,
2600 pub service_role_present: bool,
2601 pub encryption_key_present: bool,
2602 pub cloud_watch_logs_status: Option<String>,
2603 pub s3_logs_status: Option<String>,
2604 pub timeout_in_minutes: Option<i32>,
2605 pub queued_timeout_in_minutes: Option<i32>,
2606 pub created: Option<f64>,
2607 pub last_modified: Option<f64>,
2608}
2609
2610#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2611#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2612#[serde(rename_all = "camelCase")]
2613pub struct GcpCloudBuildHeartbeatData {
2614 pub status: BuildHeartbeatStatus,
2615 pub project_id: String,
2616 pub location: String,
2617 pub build_config_id: String,
2618 pub service_account: Option<String>,
2619 pub environment_variable_count: u32,
2620}
2621
2622#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2623#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2624#[serde(rename_all = "camelCase")]
2625pub struct AzureContainerAppsBuildHeartbeatData {
2626 pub status: BuildHeartbeatStatus,
2627 pub managed_environment_id: String,
2628 pub resource_group_name: String,
2629 pub managed_identity_id: Option<String>,
2630 pub resource_prefix: Option<String>,
2631 pub environment_variable_count: u32,
2632}
2633
2634#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2635#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2636#[serde(rename_all = "camelCase")]
2637pub struct KubernetesBuildHeartbeatData {
2638 pub status: BuildHeartbeatStatus,
2639 pub job_name: String,
2640 pub namespace: String,
2641 pub active: Option<i32>,
2642 pub succeeded: Option<i32>,
2643 pub failed: Option<i32>,
2644 pub start_time: Option<DateTime<Utc>>,
2645 pub completion_time: Option<DateTime<Utc>>,
2646 pub condition_count: u32,
2647 pub image_digest: Option<String>,
2648 pub events: Vec<KubernetesEventSnapshot>,
2649}
2650
2651#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2652#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2653#[serde(tag = "backend", rename_all = "camelCase")]
2654pub enum ServiceActivationHeartbeatData {
2655 GcpServiceUsage(GcpServiceUsageActivationHeartbeatData),
2656 AzureResourceProvider(AzureResourceProviderActivationHeartbeatData),
2657}
2658
2659#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2660#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2661#[serde(rename_all = "camelCase")]
2662pub struct ServiceActivationHeartbeatStatus {
2663 pub health: ObservedHealth,
2664 pub lifecycle: ProviderLifecycleState,
2665 pub message: Option<String>,
2666 pub stale: bool,
2667 pub partial: bool,
2668 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2669}
2670
2671impl Default for ServiceActivationHeartbeatStatus {
2672 fn default() -> Self {
2673 Self {
2674 health: ObservedHealth::Healthy,
2675 lifecycle: ProviderLifecycleState::Running,
2676 message: None,
2677 stale: false,
2678 partial: false,
2679 collection_issues: vec![],
2680 }
2681 }
2682}
2683
2684#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2685#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2686#[serde(rename_all = "camelCase")]
2687pub struct GcpServiceUsageActivationHeartbeatData {
2688 pub status: ServiceActivationHeartbeatStatus,
2689 pub project_id: String,
2690 pub service_name: String,
2691 pub service_resource_name: Option<String>,
2692 pub title: Option<String>,
2693 pub state: Option<String>,
2694 pub enabled: bool,
2695 pub last_operation_name: Option<String>,
2696}
2697
2698#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2699#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2700#[serde(rename_all = "camelCase")]
2701pub struct AzureResourceProviderActivationHeartbeatData {
2702 pub status: ServiceActivationHeartbeatStatus,
2703 pub namespace: String,
2704 pub provider_id: Option<String>,
2705 pub registration_state: Option<String>,
2706 pub registration_policy: Option<String>,
2707 pub resource_type_count: u32,
2708 pub registered: bool,
2709}
2710
2711#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2712#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2713#[serde(rename_all = "camelCase")]
2714pub struct AzureResourceGroupHeartbeatData {
2715 pub status: AzureResourceGroupHeartbeatStatus,
2716 pub name: String,
2717 pub resource_id: Option<String>,
2718 pub location: Option<String>,
2719 pub provisioning_state: Option<String>,
2720 pub managed_tags: BTreeMap<String, String>,
2721}
2722
2723#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2724#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2725#[serde(rename_all = "camelCase")]
2726pub struct AzureResourceGroupHeartbeatStatus {
2727 pub health: ObservedHealth,
2728 pub lifecycle: ProviderLifecycleState,
2729 pub message: Option<String>,
2730 pub stale: bool,
2731 pub partial: bool,
2732 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2733}
2734
2735impl Default for AzureResourceGroupHeartbeatStatus {
2736 fn default() -> Self {
2737 Self {
2738 health: ObservedHealth::Healthy,
2739 lifecycle: ProviderLifecycleState::Running,
2740 message: None,
2741 stale: false,
2742 partial: false,
2743 collection_issues: vec![],
2744 }
2745 }
2746}
2747
2748#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2749#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2750#[serde(rename_all = "camelCase")]
2751pub struct AzureStorageAccountHeartbeatData {
2752 pub status: StorageHeartbeatStatus,
2753 pub name: String,
2754 pub resource_id: Option<String>,
2755 pub resource_group: Option<String>,
2756 pub location: Option<String>,
2757 pub kind: Option<String>,
2758 pub sku_name: Option<String>,
2759 pub sku_tier: Option<String>,
2760 pub provisioning_state: Option<String>,
2761 pub primary_endpoints: AzureStorageAccountEndpoints,
2762 pub secondary_endpoints: AzureStorageAccountEndpoints,
2763 pub public_network_access: Option<String>,
2764 pub allow_blob_public_access: Option<bool>,
2765 pub allow_shared_key_access: Option<bool>,
2766 pub minimum_tls_version: Option<String>,
2767 pub supports_https_traffic_only: Option<bool>,
2768 pub encryption_key_source: Option<String>,
2769 pub require_infrastructure_encryption: Option<bool>,
2770 pub network_default_action: Option<String>,
2771 pub network_bypass: Option<String>,
2772 pub network_ip_rule_count: Option<u32>,
2773 pub network_virtual_network_rule_count: Option<u32>,
2774 pub network_resource_access_rule_count: Option<u32>,
2775}
2776
2777#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
2778#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2779#[serde(rename_all = "camelCase")]
2780pub struct AzureStorageAccountEndpoints {
2781 pub blob: Option<String>,
2782 pub dfs: Option<String>,
2783 pub file: Option<String>,
2784 pub queue: Option<String>,
2785 pub table: Option<String>,
2786 pub web: Option<String>,
2787}
2788
2789#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2790#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2791#[serde(rename_all = "camelCase")]
2792pub struct AzureContainerAppsEnvironmentHeartbeatData {
2793 pub status: AzureContainerAppsEnvironmentHeartbeatStatus,
2794 pub name: String,
2795 pub resource_id: Option<String>,
2796 pub resource_group: Option<String>,
2797 pub location: Option<String>,
2798 pub kind: Option<String>,
2799 pub provisioning_state: Option<String>,
2800 pub default_domain: Option<String>,
2801 pub static_ip: Option<String>,
2802 pub custom_domain_verification_id: Option<String>,
2803 pub infrastructure_resource_group: Option<String>,
2804 pub event_stream_endpoint: Option<String>,
2805 pub zone_redundant: Option<bool>,
2806 pub workload_profile_count: u32,
2807 pub workload_profiles: Vec<AzureContainerAppsEnvironmentWorkloadProfile>,
2808}
2809
2810#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2811#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2812#[serde(rename_all = "camelCase")]
2813pub struct AzureContainerAppsEnvironmentHeartbeatStatus {
2814 pub health: ObservedHealth,
2815 pub lifecycle: ProviderLifecycleState,
2816 pub message: Option<String>,
2817 pub stale: bool,
2818 pub partial: bool,
2819 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2820}
2821
2822#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2823#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2824#[serde(rename_all = "camelCase")]
2825pub struct AzureContainerAppsEnvironmentWorkloadProfile {
2826 pub name: String,
2827 pub workload_profile_type: String,
2828 pub minimum_count: Option<i32>,
2829 pub maximum_count: Option<i32>,
2830}
2831
2832#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2833#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2834#[serde(rename_all = "camelCase")]
2835pub struct AzureServiceBusNamespaceHeartbeatData {
2836 pub status: QueueHeartbeatStatus,
2837 pub name: String,
2838 pub resource_id: Option<String>,
2839 pub resource_group: Option<String>,
2840 pub location: Option<String>,
2841 pub sku_name: Option<String>,
2842 pub sku_tier: Option<String>,
2843 pub sku_capacity: Option<i32>,
2844 pub namespace_status: Option<String>,
2845 pub provisioning_state: Option<String>,
2846 pub service_bus_endpoint: Option<String>,
2847 pub metric_id: Option<String>,
2848 pub public_network_access: Option<String>,
2849 pub disable_local_auth: Option<bool>,
2850 pub minimum_tls_version: Option<String>,
2851 pub premium_messaging_partitions: Option<i32>,
2852 pub private_endpoint_connection_count: u32,
2853 pub zone_redundant: Option<bool>,
2854 pub created_at: Option<String>,
2855 pub updated_at: Option<String>,
2856}
2857
2858#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2859#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2860#[serde(rename_all = "camelCase")]
2861pub struct NamedResourceDetail {
2862 pub name: String,
2863 pub region: Option<String>,
2864}
2865
2866#[cfg(test)]
2867mod tests {
2868 use super::*;
2869 use chrono::TimeZone as _;
2870 use serde_json::json;
2871
2872 fn observed_at() -> DateTime<Utc> {
2873 Utc.with_ymd_and_hms(2026, 5, 28, 10, 30, 0).unwrap()
2874 }
2875
2876 fn workload_status() -> WorkloadHeartbeatStatus {
2877 WorkloadHeartbeatStatus {
2878 health: ObservedHealth::Healthy,
2879 lifecycle: ProviderLifecycleState::Running,
2880 message: None,
2881 stale: false,
2882 partial: false,
2883 collection_issues: vec![],
2884 }
2885 }
2886
2887 fn workload_replicas() -> WorkloadReplicaStatus {
2888 WorkloadReplicaStatus {
2889 desired: Some(2),
2890 current: Some(2),
2891 ready: Some(1),
2892 available: Some(1),
2893 updated: Some(2),
2894 misscheduled: None,
2895 }
2896 }
2897
2898 fn heartbeat(data: ResourceHeartbeatData, resource_type: &str) -> ResourceHeartbeat {
2899 ResourceHeartbeat {
2900 deployment_id: Some("dep_123".to_string()),
2901 resource_id: "api".to_string(),
2902 resource_type: ResourceType::from(resource_type),
2903 controller_platform: Platform::Kubernetes,
2904 backend: HeartbeatBackend::Kubernetes,
2905 observed_at: observed_at(),
2906 data,
2907 raw: vec![RawHeartbeatSnippet {
2908 source: "kubernetes/apps/v1/deployments/api".to_string(),
2909 format: RawHeartbeatSnippetFormat::Json,
2910 collected_at: observed_at(),
2911 body: r#"{"readyReplicas":1}"#.to_string(),
2912 truncated: false,
2913 }],
2914 }
2915 }
2916
2917 #[test]
2918 fn resource_heartbeat_roundtrips_managed_resource_data() {
2919 let heartbeat_json = serde_json::to_value(heartbeat(
2920 ResourceHeartbeatData::Container(ContainerHeartbeatData::Kubernetes(
2921 KubernetesContainerHeartbeatData {
2922 status: workload_status(),
2923 namespace: "default".to_string(),
2924 name: "api".to_string(),
2925 workload_kind: KubernetesWorkloadKind::Deployment,
2926 replicas: workload_replicas(),
2927 restarts: None,
2928 cpu: None,
2929 memory: None,
2930 workload: None,
2931 pods: vec![],
2932 events: vec![],
2933 },
2934 )),
2935 "container",
2936 ))
2937 .unwrap();
2938
2939 let parsed: ResourceHeartbeat = serde_json::from_value(heartbeat_json).unwrap();
2940 assert_eq!(parsed.resource_id, "api");
2941 assert!(matches!(
2942 parsed.data,
2943 ResourceHeartbeatData::Container(ContainerHeartbeatData::Kubernetes(_))
2944 ));
2945 }
2946
2947 #[test]
2948 fn local_daemon_heartbeat_defaults_missing_daemon_name() {
2949 let mut value =
2950 serde_json::to_value(DaemonHeartbeatData::Local(LocalDaemonHeartbeatData {
2951 status: workload_status(),
2952 daemon_name: "agent".to_string(),
2953 runtime_id: "local-agent".to_string(),
2954 pid: None,
2955 command_supported: false,
2956 image_path_present: true,
2957 restart_count: None,
2958 exit_reason: None,
2959 daemon_instance: None,
2960 events: vec![],
2961 }))
2962 .unwrap();
2963
2964 value.as_object_mut().unwrap().remove("daemonName");
2965
2966 let parsed: DaemonHeartbeatData = serde_json::from_value(value).unwrap();
2967 match parsed {
2968 DaemonHeartbeatData::Local(data) => assert_eq!(data.daemon_name, ""),
2969 other => panic!("expected local daemon heartbeat, got {other:?}"),
2970 }
2971 }
2972
2973 #[test]
2974 fn container_heartbeat_serializes_resource_first_data() {
2975 let heartbeat = heartbeat(
2976 ResourceHeartbeatData::Container(ContainerHeartbeatData::Kubernetes(
2977 KubernetesContainerHeartbeatData {
2978 status: workload_status(),
2979 namespace: "default".to_string(),
2980 name: "api".to_string(),
2981 workload_kind: KubernetesWorkloadKind::Deployment,
2982 replicas: workload_replicas(),
2983 restarts: Some(1),
2984 cpu: Some(MetricSample {
2985 value: 0.5,
2986 unit: MetricUnit::Cores,
2987 }),
2988 memory: None,
2989 workload: None,
2990 pods: vec![],
2991 events: vec![],
2992 },
2993 )),
2994 "container",
2995 );
2996
2997 let value = serde_json::to_value(&heartbeat).unwrap();
2998
2999 assert_eq!(value["resourceType"], "container");
3000 assert_eq!(value["data"]["resourceType"], "container");
3001 assert_eq!(value["data"]["data"]["backend"], "kubernetes");
3002 assert_eq!(value["raw"][0]["body"], r#"{"readyReplicas":1}"#);
3003 assert!(value.get("collection").is_none());
3004 assert!(value["data"]["data"].get("summary").is_none());
3005 assert!(value["data"]["data"].get("detail").is_none());
3006 }
3007
3008 #[test]
3009 fn representative_workload_data_has_stable_tags() {
3010 let daemon = serde_json::to_value(ResourceHeartbeatData::Daemon(
3011 DaemonHeartbeatData::Kubernetes(KubernetesDaemonHeartbeatData {
3012 status: workload_status(),
3013 namespace: "default".to_string(),
3014 name: "agent".to_string(),
3015 replicas: workload_replicas(),
3016 restarts: Some(0),
3017 command_supported: true,
3018 cpu: None,
3019 memory: None,
3020 workload: None,
3021 pods: vec![],
3022 events: vec![],
3023 }),
3024 ))
3025 .unwrap();
3026 let worker = serde_json::to_value(ResourceHeartbeatData::Worker(
3027 WorkerHeartbeatData::AwsLambda(AwsLambdaWorkerHeartbeatData {
3028 status: workload_status(),
3029 function_name: "handler".to_string(),
3030 runtime: Some("nodejs22.x".to_string()),
3031 package_type: None,
3032 memory_size_mb: None,
3033 timeout_seconds: None,
3034 version: None,
3035 revision_id: None,
3036 last_modified: None,
3037 state: None,
3038 state_reason: None,
3039 state_reason_code: None,
3040 last_update_status: None,
3041 last_update_status_reason: None,
3042 last_update_status_reason_code: None,
3043 code_sha256: None,
3044 layer_count: 0,
3045 function_url_auth_type: None,
3046 function_url_cors_present: false,
3047 trigger_count: 0,
3048 }),
3049 ))
3050 .unwrap();
3051
3052 assert_eq!(daemon["resourceType"], "daemon");
3053 assert_eq!(daemon["data"]["backend"], "kubernetes");
3054 assert_eq!(worker["resourceType"], "worker");
3055 assert_eq!(worker["data"]["backend"], "awsLambda");
3056 }
3057
3058 #[test]
3061 fn gcp_sandbox_heartbeat_keeps_its_wire_tag_and_camel_case_names() {
3062 let data = ResourceHeartbeatData::Sandbox(SandboxHeartbeatData::GcpAgentPlatform(
3063 GcpAgentPlatformSandboxHeartbeatData {
3064 status: SandboxHeartbeatStatus::default(),
3065 engine: "eng".to_string(),
3066 template_id: "tpl1".to_string(),
3067 },
3068 ));
3069
3070 let value = serde_json::to_value(&data).unwrap();
3071 assert_eq!(
3072 value,
3073 json!({
3074 "resourceType": "sandbox",
3075 "data": {
3076 "backend": "gcpAgentPlatform",
3077 "status": {
3078 "health": "healthy",
3079 "lifecycle": "running",
3080 "message": null,
3081 "stale": false,
3082 "partial": false,
3083 "collectionIssues": []
3084 },
3085 "engine": "eng",
3086 "templateId": "tpl1"
3087 }
3088 })
3089 );
3090
3091 let parsed: ResourceHeartbeatData = serde_json::from_value(value).unwrap();
3092 assert_eq!(parsed, data);
3093 }
3094
3095 #[test]
3096 fn representative_cluster_and_data_variants_have_optional_counts() {
3097 let cluster = serde_json::to_value(ResourceHeartbeatData::KubernetesCluster(
3098 KubernetesClusterHeartbeatData {
3099 status: WorkloadHeartbeatStatus {
3100 health: ObservedHealth::Healthy,
3101 lifecycle: ProviderLifecycleState::Running,
3102 message: None,
3103 stale: false,
3104 partial: false,
3105 collection_issues: vec![],
3106 },
3107 node_counts: ObservedCounts {
3108 desired: Some(3),
3109 current: Some(3),
3110 ready: None,
3111 },
3112 pod_counts: ObservedCounts {
3113 desired: None,
3114 current: Some(12),
3115 ready: Some(11),
3116 },
3117 cpu: None,
3118 memory: None,
3119 name: "prod".to_string(),
3120 region: Some("us-east-1".to_string()),
3121 namespace: None,
3122 version: Some("1.33".to_string()),
3123 node_statuses: vec![],
3124 events: vec![],
3125 },
3126 ))
3127 .unwrap();
3128 let queue = serde_json::to_value(ResourceHeartbeatData::Queue(QueueHeartbeatData::AwsSqs(
3129 AwsSqsQueueHeartbeatData {
3130 status: QueueHeartbeatStatus {
3131 health: ObservedHealth::Healthy,
3132 lifecycle: ProviderLifecycleState::Running,
3133 message: None,
3134 stale: false,
3135 partial: false,
3136 collection_issues: vec![],
3137 },
3138 name: "jobs".to_string(),
3139 region: Some("us-east-1".to_string()),
3140 queue_url: Some("https://sqs.us-east-1.amazonaws.com/123/jobs".to_string()),
3141 queue_arn: Some("arn:aws:sqs:us-east-1:123:jobs".to_string()),
3142 visibility_timeout_seconds: Some(30),
3143 message_retention_period_seconds: Some(345600),
3144 delay_seconds: Some(0),
3145 receive_message_wait_time_seconds: Some(0),
3146 maximum_message_size: Some(262144),
3147 redrive_policy: None,
3148 redrive_allow_policy: None,
3149 fifo_queue: Some(false),
3150 content_based_deduplication: None,
3151 deduplication_scope: None,
3152 fifo_throughput_limit: None,
3153 sse_enabled: Some(false),
3154 kms_master_key_id: None,
3155 kms_data_key_reuse_period_seconds: None,
3156 sqs_managed_sse_enabled: Some(false),
3157 approximate_visible_messages: Some(42),
3158 approximate_in_flight_messages: Some(1),
3159 approximate_delayed_messages: Some(0),
3160 approximate_counts: true,
3161 },
3162 )))
3163 .unwrap();
3164 let storage = serde_json::to_value(ResourceHeartbeatData::Storage(
3165 StorageHeartbeatData::AwsS3(AwsS3StorageHeartbeatData {
3166 status: StorageHeartbeatStatus {
3167 health: ObservedHealth::Healthy,
3168 lifecycle: ProviderLifecycleState::Running,
3169 message: None,
3170 stale: false,
3171 partial: false,
3172 collection_issues: vec![],
3173 },
3174 name: "assets".to_string(),
3175 region: Some("us-east-1".to_string()),
3176 bucket_location: Some("us-east-1".to_string()),
3177 versioning_status: Some("Enabled".to_string()),
3178 versioning_enabled: Some(true),
3179 lifecycle_present: false,
3180 lifecycle_rule_count: Some(0),
3181 encryption_config_present: true,
3182 encryption_enabled: Some(true),
3183 public_access_block_present: true,
3184 block_public_acls: Some(true),
3185 ignore_public_acls: Some(true),
3186 block_public_policy: Some(true),
3187 restrict_public_buckets: Some(true),
3188 bucket_policy_present: Some(false),
3189 bucket_acl_present: Some(true),
3190 }),
3191 ))
3192 .unwrap();
3193 let gcp_storage = serde_json::to_value(ResourceHeartbeatData::Storage(
3194 StorageHeartbeatData::GcpCloudStorage(GcpCloudStorageHeartbeatData {
3195 status: StorageHeartbeatStatus {
3196 health: ObservedHealth::Healthy,
3197 lifecycle: ProviderLifecycleState::Running,
3198 message: None,
3199 stale: false,
3200 partial: false,
3201 collection_issues: vec![],
3202 },
3203 name: "assets".to_string(),
3204 bucket_id: Some("project/assets".to_string()),
3205 location: Some("US".to_string()),
3206 location_type: Some("multi-region".to_string()),
3207 storage_class: Some("STANDARD".to_string()),
3208 versioning_enabled: Some(true),
3209 lifecycle_present: false,
3210 lifecycle_rule_count: Some(0),
3211 retention_policy_effective_time: None,
3212 retention_policy_is_locked: None,
3213 retention_period: None,
3214 soft_delete_retention_duration_seconds: None,
3215 soft_delete_effective_time: None,
3216 uniform_bucket_level_access_enabled: Some(true),
3217 uniform_bucket_level_access_locked_time: None,
3218 public_access_prevention: Some("enforced".to_string()),
3219 encryption_config_present: true,
3220 default_kms_key_name: Some(
3221 "projects/p/locations/l/keyRings/r/cryptoKeys/k".to_string(),
3222 ),
3223 }),
3224 ))
3225 .unwrap();
3226 let kv = serde_json::to_value(ResourceHeartbeatData::Kv(KvHeartbeatData::AwsDynamoDb(
3227 AwsDynamoDbKvHeartbeatData {
3228 status: KvHeartbeatStatus {
3229 health: ObservedHealth::Healthy,
3230 lifecycle: ProviderLifecycleState::Running,
3231 message: None,
3232 stale: false,
3233 partial: false,
3234 collection_issues: vec![],
3235 },
3236 name: "state".to_string(),
3237 region: Some("us-east-1".to_string()),
3238 table_arn: None,
3239 table_status: Some("ACTIVE".to_string()),
3240 billing_mode: Some("PAY_PER_REQUEST".to_string()),
3241 key_schema: vec![AwsDynamoDbKeySchemaElement {
3242 attribute_name: "pk".to_string(),
3243 key_type: "HASH".to_string(),
3244 }],
3245 global_secondary_index_count: Some(0),
3246 local_secondary_index_count: Some(0),
3247 item_count: None,
3248 table_size_bytes: None,
3249 stream_enabled: Some(false),
3250 stream_view_type: None,
3251 ttl_status: Some("ENABLED".to_string()),
3252 ttl_attribute_name: Some("ttl".to_string()),
3253 deletion_protection_enabled: Some(false),
3254 sse_status: Some("ENABLED".to_string()),
3255 sse_type: Some("KMS".to_string()),
3256 table_class: None,
3257 replica_count: Some(0),
3258 restore_in_progress: None,
3259 },
3260 )))
3261 .unwrap();
3262
3263 assert_eq!(cluster["resourceType"], "kubernetes-cluster");
3264 assert!(cluster["data"].get("summary").is_none());
3265 assert!(cluster["data"].get("detail").is_none());
3266 assert_eq!(cluster["data"]["name"], "prod");
3267 assert_eq!(queue["data"]["backend"], "awsSqs");
3268 assert_eq!(queue["data"]["approximateVisibleMessages"], 42);
3269 assert!(queue["data"].get("summary").is_none());
3270 assert_eq!(storage["data"]["backend"], "awsS3");
3271 assert!(storage["data"].get("summary").is_none());
3272 assert_eq!(gcp_storage["data"]["backend"], "gcpCloudStorage");
3273 assert_eq!(gcp_storage["data"]["publicAccessPrevention"], "enforced");
3274 assert_eq!(kv["data"]["backend"], "awsDynamoDb");
3275 assert!(kv["data"].get("summary").is_none());
3276 assert_eq!(kv["data"]["itemCount"], json!(null));
3277 }
3278
3279 #[test]
3280 fn ai_heartbeat_serializes_stable_tags() {
3281 let aws = serde_json::to_value(ResourceHeartbeatData::Ai(AiHeartbeatData::AwsBedrock(
3282 AwsBedrockAiHeartbeatData {
3283 status: AiHeartbeatStatus::default(),
3284 region: "us-east-1".to_string(),
3285 availability: AiAvailabilityObservation::unobserved(
3286 AiAvailabilitySource::AwsBedrock,
3287 Platform::Aws,
3288 Some("us-east-1".to_string()),
3289 ),
3290 },
3291 )))
3292 .unwrap();
3293 let gcp = serde_json::to_value(ResourceHeartbeatData::Ai(AiHeartbeatData::GcpVertex(
3294 GcpVertexAiHeartbeatData {
3295 status: AiHeartbeatStatus::default(),
3296 project: "my-project".to_string(),
3297 location: "us-central1".to_string(),
3298 availability: AiAvailabilityObservation::unobserved(
3299 AiAvailabilitySource::GcpVertex,
3300 Platform::Gcp,
3301 Some("us-central1".to_string()),
3302 ),
3303 },
3304 )))
3305 .unwrap();
3306 let azure = serde_json::to_value(ResourceHeartbeatData::Ai(AiHeartbeatData::AzureFoundry(
3307 AzureFoundryAiHeartbeatData {
3308 status: AiHeartbeatStatus::default(),
3309 account_name: "my-ai-account".to_string(),
3310 endpoint: Some("https://my-ai-account.openai.azure.com/".to_string()),
3311 resource_group: Some("my-rg".to_string()),
3312 location: Some("eastus".to_string()),
3313 availability: AiAvailabilityObservation::unobserved(
3314 AiAvailabilitySource::AzureFoundry,
3315 Platform::Azure,
3316 Some("eastus".to_string()),
3317 ),
3318 },
3319 )))
3320 .unwrap();
3321
3322 assert_eq!(aws["resourceType"], "ai");
3323 assert_eq!(aws["data"]["backend"], "awsBedrock");
3324 assert_eq!(aws["data"]["region"], "us-east-1");
3325 assert!(aws["data"].get("summary").is_none());
3326
3327 assert_eq!(gcp["resourceType"], "ai");
3328 assert_eq!(gcp["data"]["backend"], "gcpVertex");
3329 assert_eq!(gcp["data"]["project"], "my-project");
3330 assert_eq!(gcp["data"]["location"], "us-central1");
3331
3332 assert_eq!(azure["resourceType"], "ai");
3333 assert_eq!(azure["data"]["backend"], "azureFoundry");
3334 assert_eq!(azure["data"]["accountName"], "my-ai-account");
3335 assert_eq!(
3336 azure["data"]["endpoint"],
3337 "https://my-ai-account.openai.azure.com/"
3338 );
3339 }
3340}