1use std::collections::BTreeMap;
2
3use crate::{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,
14 pub resource_type: ResourceType,
15 pub controller_platform: Platform,
16 pub backend: HeartbeatBackend,
17 pub observed_at: DateTime<Utc>,
18 pub data: ResourceHeartbeatData,
19 pub raw: Vec<RawHeartbeatSnippet>,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
23#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
24#[serde(rename_all = "camelCase")]
25pub enum HeartbeatBackend {
26 Aws,
27 Gcp,
28 Azure,
29 Kubernetes,
30 Local,
31 Managed,
32 External,
33 Test,
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
37#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
38#[serde(rename_all = "kebab-case")]
39pub enum HeartbeatCollectionIssueReason {
40 Forbidden,
41 NotInstalled,
42 ApiUnavailable,
43 CollectionFailed,
44 TimedOut,
45}
46
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
49#[serde(tag = "resourceType", content = "data")]
50pub enum ResourceHeartbeatData {
51 #[serde(rename = "storage")]
52 Storage(StorageHeartbeatData),
53 #[serde(rename = "worker")]
54 Worker(WorkerHeartbeatData),
55 #[serde(rename = "container")]
56 Container(ContainerHeartbeatData),
57 #[serde(rename = "daemon")]
58 Daemon(DaemonHeartbeatData),
59 #[serde(rename = "compute-cluster")]
60 ComputeCluster(ComputeClusterHeartbeatData),
61 #[serde(rename = "kubernetes-cluster")]
62 KubernetesCluster(KubernetesClusterHeartbeatData),
63 #[serde(rename = "queue")]
64 Queue(QueueHeartbeatData),
65 #[serde(rename = "kv")]
66 Kv(KvHeartbeatData),
67 #[serde(rename = "vault")]
68 Vault(VaultHeartbeatData),
69 #[serde(rename = "service-account")]
70 ServiceAccount(ServiceAccountHeartbeatData),
71 #[serde(rename = "network")]
72 Network(NetworkHeartbeatData),
73 #[serde(rename = "remote-stack-management")]
74 RemoteStackManagement(RemoteStackManagementHeartbeatData),
75 #[serde(rename = "artifact-registry")]
76 ArtifactRegistry(ArtifactRegistryHeartbeatData),
77 #[serde(rename = "build")]
78 Build(BuildHeartbeatData),
79 #[serde(rename = "service_activation")]
80 ServiceActivation(ServiceActivationHeartbeatData),
81 #[serde(rename = "azure_resource_group")]
82 AzureResourceGroup(AzureResourceGroupHeartbeatData),
83 #[serde(rename = "azure_storage_account")]
84 AzureStorageAccount(AzureStorageAccountHeartbeatData),
85 #[serde(rename = "azure_container_apps_environment")]
86 AzureContainerAppsEnvironment(AzureContainerAppsEnvironmentHeartbeatData),
87 #[serde(rename = "azure_service_bus_namespace")]
88 AzureServiceBusNamespace(AzureServiceBusNamespaceHeartbeatData),
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
92#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
93#[serde(rename_all = "kebab-case")]
94pub enum ObservedHealth {
95 Unknown,
96 Healthy,
97 Degraded,
98 Unhealthy,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
102#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
103#[serde(rename_all = "kebab-case")]
104pub enum ProviderLifecycleState {
105 Unknown,
106 Creating,
107 Updating,
108 Running,
109 Scaling,
110 Stopping,
111 Stopped,
112 Deleting,
113 Deleted,
114 Failed,
115}
116
117#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
118#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
119#[serde(rename_all = "camelCase")]
120pub struct HeartbeatCollectionIssue {
121 pub source: String,
122 pub reason: HeartbeatCollectionIssueReason,
123 pub severity: HeartbeatIssueSeverity,
124 pub message: String,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
128#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
129#[serde(rename_all = "kebab-case")]
130pub enum HeartbeatIssueSeverity {
131 Info,
132 Warning,
133 Error,
134}
135
136#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
137#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
138#[serde(rename_all = "camelCase")]
139pub struct KubernetesEventSnapshot {
140 pub reason: String,
141 #[serde(rename = "type")]
142 pub type_: Option<String>,
143 pub message: String,
144 pub count: Option<i32>,
145 pub first_timestamp: Option<DateTime<Utc>>,
146 pub last_timestamp: Option<DateTime<Utc>>,
147 pub event_time: Option<DateTime<Utc>>,
148 pub source: Option<KubernetesEventSource>,
149 pub involved_object: Option<KubernetesEventInvolvedObject>,
150 pub raw: Option<JsonValue>,
151}
152
153#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
154#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
155#[serde(rename_all = "camelCase")]
156pub struct KubernetesEventSource {
157 pub component: Option<String>,
158 pub host: Option<String>,
159}
160
161#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
162#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
163#[serde(rename_all = "camelCase")]
164pub struct KubernetesEventInvolvedObject {
165 pub kind: Option<String>,
166 pub namespace: Option<String>,
167 pub name: Option<String>,
168 pub uid: Option<String>,
169 pub api_version: Option<String>,
170 pub resource_version: Option<String>,
171 pub field_path: Option<String>,
172}
173
174#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
175#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
176#[serde(rename_all = "camelCase")]
177pub struct ManagedRuntimeEventSnapshot {
178 pub event_id: Option<String>,
179 pub reason: String,
180 #[serde(rename = "type")]
181 pub type_: Option<String>,
182 pub message: String,
183 pub count: Option<i32>,
184 pub first_timestamp: Option<DateTime<Utc>>,
185 pub last_timestamp: Option<DateTime<Utc>>,
186 pub event_time: Option<DateTime<Utc>>,
187 pub source: Option<ManagedRuntimeEventSource>,
188 pub involved_object: Option<ManagedRuntimeEventInvolvedObject>,
189 pub details: Option<JsonValue>,
190 pub raw: Option<JsonValue>,
191}
192
193#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
194#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
195#[serde(rename_all = "camelCase")]
196pub struct ManagedRuntimeEventSource {
197 pub component: Option<String>,
198 pub host: Option<String>,
199}
200
201#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
202#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
203#[serde(rename_all = "camelCase")]
204pub struct ManagedRuntimeEventInvolvedObject {
205 pub kind: Option<String>,
206 pub id: Option<String>,
207 pub name: Option<String>,
208 pub replica_id: Option<String>,
209 pub machine_id: Option<String>,
210 pub details: Option<JsonValue>,
211}
212
213#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
214#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
215#[serde(rename_all = "camelCase")]
216pub struct LocalRuntimeEventSnapshot {
217 pub timestamp: DateTime<Utc>,
218 pub severity: HeartbeatIssueSeverity,
219 pub kind: String,
220 pub message: String,
221 pub subject: Option<LocalRuntimeEventSubject>,
222 pub raw: Option<JsonValue>,
223}
224
225#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
226#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
227#[serde(rename_all = "camelCase")]
228pub struct LocalRuntimeEventSubject {
229 pub kind: String,
230 pub id: Option<String>,
231 pub name: Option<String>,
232}
233
234#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
235#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
236#[serde(rename_all = "camelCase")]
237pub struct RawHeartbeatSnippet {
238 pub source: String,
239 pub format: RawHeartbeatSnippetFormat,
240 pub collected_at: DateTime<Utc>,
241 pub body: String,
242 pub truncated: bool,
243}
244
245#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
246#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
247#[serde(rename_all = "kebab-case")]
248pub enum RawHeartbeatSnippetFormat {
249 Json,
250 Yaml,
251 Text,
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
255#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
256#[serde(rename_all = "camelCase")]
257pub struct ObservedCounts {
258 pub desired: Option<u32>,
259 pub current: Option<u32>,
260 pub ready: Option<u32>,
261}
262
263#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
264#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
265#[serde(rename_all = "camelCase")]
266pub struct MetricSample {
267 pub value: f64,
268 pub unit: MetricUnit,
269}
270
271#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
272#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
273#[serde(rename_all = "kebab-case")]
274pub enum MetricUnit {
275 Count,
276 Percent,
277 Bytes,
278 Cores,
279 Milliseconds,
280 RequestsPerSecond,
281}
282
283#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
284#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
285#[serde(tag = "backend", rename_all = "camelCase")]
286pub enum StorageHeartbeatData {
287 AwsS3(AwsS3StorageHeartbeatData),
288 GcpCloudStorage(GcpCloudStorageHeartbeatData),
289 AzureBlob(AzureBlobStorageHeartbeatData),
290 Local(LocalStorageHeartbeatData),
291}
292
293#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
294#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
295#[serde(rename_all = "camelCase")]
296pub struct StorageHeartbeatStatus {
297 pub health: ObservedHealth,
298 pub lifecycle: ProviderLifecycleState,
299 pub message: Option<String>,
300 pub stale: bool,
301 pub partial: bool,
302 pub collection_issues: Vec<HeartbeatCollectionIssue>,
303}
304
305#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
306#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
307#[serde(rename_all = "camelCase")]
308pub struct AwsS3StorageHeartbeatData {
309 pub status: StorageHeartbeatStatus,
310 pub name: String,
311 pub region: Option<String>,
312 pub bucket_location: Option<String>,
313 pub versioning_status: Option<String>,
314 pub versioning_enabled: Option<bool>,
315 pub lifecycle_present: bool,
316 pub lifecycle_rule_count: Option<u64>,
317 pub encryption_config_present: bool,
318 pub encryption_enabled: Option<bool>,
319 pub public_access_block_present: bool,
320 pub block_public_acls: Option<bool>,
321 pub ignore_public_acls: Option<bool>,
322 pub block_public_policy: Option<bool>,
323 pub restrict_public_buckets: Option<bool>,
324 pub bucket_policy_present: Option<bool>,
325 pub bucket_acl_present: Option<bool>,
326}
327
328#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
329#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
330#[serde(rename_all = "camelCase")]
331pub struct AzureBlobStorageHeartbeatData {
332 pub status: StorageHeartbeatStatus,
333 pub name: String,
334 pub storage_account_name: Option<String>,
335 pub resource_group: Option<String>,
336 pub location: Option<String>,
337 pub account_kind: Option<String>,
338 pub sku_name: Option<String>,
339 pub sku_tier: Option<String>,
340 pub access_tier: Option<String>,
341 pub provisioning_state: Option<String>,
342 pub primary_location: Option<String>,
343 pub secondary_location: Option<String>,
344 pub status_of_primary: Option<String>,
345 pub status_of_secondary: Option<String>,
346 pub public_network_access: Option<String>,
347 pub allow_blob_public_access: Option<bool>,
348 pub encryption_key_source: Option<String>,
349 pub blob_encryption_enabled: Option<bool>,
350 pub file_encryption_enabled: Option<bool>,
351 pub queue_encryption_enabled: Option<bool>,
352 pub table_encryption_enabled: Option<bool>,
353 pub blob_versioning_enabled: Option<bool>,
354 pub blob_delete_retention_enabled: Option<bool>,
355 pub blob_delete_retention_days: Option<u64>,
356 pub container_delete_retention_enabled: Option<bool>,
357 pub container_delete_retention_days: Option<u64>,
358 pub change_feed_enabled: Option<bool>,
359 pub change_feed_retention_days: Option<u64>,
360 pub container_public_access: Option<String>,
361}
362
363#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
364#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
365#[serde(rename_all = "camelCase")]
366pub struct GcpCloudStorageHeartbeatData {
367 pub status: StorageHeartbeatStatus,
368 pub name: String,
369 pub bucket_id: Option<String>,
370 pub location: Option<String>,
371 pub location_type: Option<String>,
372 pub storage_class: Option<String>,
373 pub versioning_enabled: Option<bool>,
374 pub lifecycle_present: bool,
375 pub lifecycle_rule_count: Option<u64>,
376 pub retention_policy_effective_time: Option<String>,
377 pub retention_policy_is_locked: Option<bool>,
378 pub retention_period: Option<String>,
379 pub soft_delete_retention_duration_seconds: Option<String>,
380 pub soft_delete_effective_time: Option<String>,
381 pub uniform_bucket_level_access_enabled: Option<bool>,
382 pub uniform_bucket_level_access_locked_time: Option<String>,
383 pub public_access_prevention: Option<String>,
384 pub encryption_config_present: bool,
385 pub default_kms_key_name: Option<String>,
386}
387
388#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
389#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
390#[serde(rename_all = "camelCase")]
391pub struct LocalStorageHeartbeatData {
392 pub status: StorageHeartbeatStatus,
393 pub path: String,
394 pub path_exists: bool,
395 pub is_directory: Option<bool>,
396 pub readonly: Option<bool>,
397 pub modified_at: Option<DateTime<Utc>>,
398}
399
400#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
401#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
402#[serde(tag = "backend", rename_all = "camelCase")]
403pub enum WorkerHeartbeatData {
404 AwsLambda(AwsLambdaWorkerHeartbeatData),
405 GcpCloudRun(GcpCloudRunWorkerHeartbeatData),
406 AzureContainerApps(AzureContainerAppsWorkerHeartbeatData),
407 Kubernetes(KubernetesWorkerHeartbeatData),
408 Local(LocalWorkerHeartbeatData),
409}
410
411#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
412#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
413#[serde(tag = "backend", rename_all = "camelCase")]
414pub enum ContainerHeartbeatData {
415 HorizonPlatform(HorizonContainerHeartbeatData),
416 Kubernetes(KubernetesContainerHeartbeatData),
417 Local(LocalContainerHeartbeatData),
418}
419
420#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
421#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
422#[serde(tag = "backend", rename_all = "camelCase")]
423pub enum DaemonHeartbeatData {
424 Aws(AwsDaemonHeartbeatData),
425 Gcp(GcpDaemonHeartbeatData),
426 Azure(AzureDaemonHeartbeatData),
427 Kubernetes(KubernetesDaemonHeartbeatData),
428 Local(LocalDaemonHeartbeatData),
429}
430
431#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
432#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
433#[serde(rename_all = "camelCase")]
434pub struct WorkloadHeartbeatStatus {
435 pub health: ObservedHealth,
436 pub lifecycle: ProviderLifecycleState,
437 pub message: Option<String>,
438 pub stale: bool,
439 pub partial: bool,
440 pub collection_issues: Vec<HeartbeatCollectionIssue>,
441}
442
443#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
444#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
445#[serde(rename_all = "camelCase")]
446pub struct WorkloadReplicaStatus {
447 pub desired: Option<u32>,
448 pub current: Option<u32>,
449 pub ready: Option<u32>,
450 pub available: Option<u32>,
451 pub updated: Option<u32>,
452 pub misscheduled: Option<u32>,
453}
454
455#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
456#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
457#[serde(rename_all = "camelCase")]
458pub struct AwsLambdaWorkerHeartbeatData {
459 pub status: WorkloadHeartbeatStatus,
460 pub function_name: String,
461 pub runtime: Option<String>,
462 pub package_type: Option<String>,
463 pub memory_size_mb: Option<i64>,
464 pub timeout_seconds: Option<i64>,
465 pub version: Option<String>,
466 pub revision_id: Option<String>,
467 pub last_modified: Option<String>,
468 pub state: Option<String>,
469 pub state_reason: Option<String>,
470 pub state_reason_code: Option<String>,
471 pub last_update_status: Option<String>,
472 pub last_update_status_reason: Option<String>,
473 pub last_update_status_reason_code: Option<String>,
474 pub code_sha256: Option<String>,
475 pub layer_count: u32,
476 pub function_url_auth_type: Option<String>,
477 pub function_url_cors_present: bool,
478 pub trigger_count: u32,
479}
480
481#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
482#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
483#[serde(rename_all = "camelCase")]
484pub struct GcpCloudRunWorkerHeartbeatData {
485 pub status: WorkloadHeartbeatStatus,
486 pub service: String,
487 pub region: Option<String>,
488 pub uri: Option<String>,
489 pub urls: Vec<String>,
490 pub latest_created_revision: Option<String>,
491 pub latest_ready_revision: Option<String>,
492 pub generation: Option<i64>,
493 pub observed_generation: Option<i64>,
494 pub traffic_count: u32,
495 pub min_instance_count: Option<i32>,
496 pub max_instance_count: Option<i32>,
497 pub container_image: Option<String>,
498 pub cpu_limit: Option<String>,
499 pub memory_limit: Option<String>,
500}
501
502#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
503#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
504#[serde(rename_all = "camelCase")]
505pub struct AzureContainerAppsWorkerHeartbeatData {
506 pub status: WorkloadHeartbeatStatus,
507 pub app_name: String,
508 pub revision: Option<String>,
509 pub environment_name: Option<String>,
510 pub provisioning_state: Option<String>,
511 pub running_status: Option<String>,
512 pub ingress_fqdn: Option<String>,
513 pub min_replicas: Option<i32>,
514 pub max_replicas: Option<i32>,
515 pub cpu: Option<f64>,
516 pub memory: Option<String>,
517}
518
519#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
520#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
521#[serde(rename_all = "camelCase")]
522pub struct KubernetesWorkerHeartbeatData {
523 pub status: WorkloadHeartbeatStatus,
524 pub namespace: String,
525 pub name: String,
526 pub workload_kind: KubernetesWorkloadKind,
527 pub replicas: WorkloadReplicaStatus,
528 pub restarts: Option<u32>,
529 pub cpu: Option<MetricSample>,
530 pub memory: Option<MetricSample>,
531 pub workload: Option<KubernetesWorkloadStatus>,
532 pub pods: Vec<KubernetesPodRuntimeUnitStatus>,
533 pub trigger_count: u32,
534 pub events: Vec<KubernetesEventSnapshot>,
535}
536
537#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
538#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
539#[serde(rename_all = "camelCase")]
540pub struct LocalWorkerHeartbeatData {
541 pub status: WorkloadHeartbeatStatus,
542 pub pid: Option<u32>,
543 pub command_supported: bool,
544 pub image_path_present: bool,
545 pub readiness_probe_ok: Option<bool>,
546 pub trigger_count: u32,
547 pub cpu: Option<MetricSample>,
548 pub memory: Option<MetricSample>,
549 pub process: Option<LocalRuntimeUnitStatus>,
550 pub events: Vec<LocalRuntimeEventSnapshot>,
551}
552
553#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
554#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
555#[serde(rename_all = "camelCase")]
556pub struct HorizonContainerHeartbeatData {
557 pub status: WorkloadHeartbeatStatus,
558 pub container_id: String,
559 pub image: Option<String>,
560 pub scheduling_mode: HorizonWorkloadSchedulingMode,
561 pub replicas: WorkloadReplicaStatus,
562 pub cpu: Option<MetricSample>,
563 pub memory: Option<MetricSample>,
564 pub attention_count: u32,
565 pub replica_units: Vec<ManagedRuntimeUnitStatus>,
566 pub events: Vec<ManagedRuntimeEventSnapshot>,
567}
568
569#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
570#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
571#[serde(rename_all = "camelCase")]
572pub enum HorizonWorkloadSchedulingMode {
573 Replicated,
574 Stateful,
575 Daemon,
576}
577
578#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
579#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
580#[serde(rename_all = "camelCase")]
581pub struct KubernetesContainerHeartbeatData {
582 pub status: WorkloadHeartbeatStatus,
583 pub namespace: String,
584 pub name: String,
585 pub workload_kind: KubernetesWorkloadKind,
586 pub replicas: WorkloadReplicaStatus,
587 pub restarts: Option<u32>,
588 pub cpu: Option<MetricSample>,
589 pub memory: Option<MetricSample>,
590 pub workload: Option<KubernetesWorkloadStatus>,
591 pub pods: Vec<KubernetesPodRuntimeUnitStatus>,
592 pub events: Vec<KubernetesEventSnapshot>,
593}
594
595#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
596#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
597#[serde(rename_all = "camelCase")]
598pub struct LocalContainerHeartbeatData {
599 pub status: WorkloadHeartbeatStatus,
600 pub container_id: Option<String>,
601 pub name: Option<String>,
602 pub image: Option<String>,
603 pub runtime_status: Option<String>,
604 pub restart_count: Option<u32>,
605 pub port_count: u32,
606 pub bind_mount_count: u32,
607 pub local_url: Option<String>,
608 pub runtime_reachable: bool,
609 pub cpu: Option<MetricSample>,
610 pub memory: Option<MetricSample>,
611 pub container_unit: Option<LocalRuntimeUnitStatus>,
612 pub events: Vec<LocalRuntimeEventSnapshot>,
613}
614
615#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
616#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
617#[serde(rename_all = "camelCase")]
618pub struct AwsDaemonHeartbeatData {
619 pub status: WorkloadHeartbeatStatus,
620 pub horizon_cluster_id: String,
621 pub daemon_name: String,
622 pub horizon_status: String,
623 pub horizon_status_reason: Option<String>,
624 pub horizon_status_message: Option<String>,
625 pub capacity_group: String,
626 pub desired_machines: u32,
627 pub assigned_machines: u32,
628 pub healthy_instances: u32,
629 pub unavailable_instances: u32,
630 pub command_supported: bool,
631 pub latest_update_timestamp: String,
632 pub daemon_instances: Vec<ManagedRuntimeUnitStatus>,
633 pub events: Vec<ManagedRuntimeEventSnapshot>,
634}
635
636#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
637#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
638#[serde(rename_all = "camelCase")]
639pub struct GcpDaemonHeartbeatData {
640 pub status: WorkloadHeartbeatStatus,
641 pub horizon_cluster_id: String,
642 pub daemon_name: String,
643 pub horizon_status: String,
644 pub horizon_status_reason: Option<String>,
645 pub horizon_status_message: Option<String>,
646 pub capacity_group: String,
647 pub desired_machines: u32,
648 pub assigned_machines: u32,
649 pub healthy_instances: u32,
650 pub unavailable_instances: u32,
651 pub command_supported: bool,
652 pub latest_update_timestamp: String,
653 pub daemon_instances: Vec<ManagedRuntimeUnitStatus>,
654 pub events: Vec<ManagedRuntimeEventSnapshot>,
655}
656
657#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
658#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
659#[serde(rename_all = "camelCase")]
660pub struct AzureDaemonHeartbeatData {
661 pub status: WorkloadHeartbeatStatus,
662 pub horizon_cluster_id: String,
663 pub daemon_name: String,
664 pub horizon_status: String,
665 pub horizon_status_reason: Option<String>,
666 pub horizon_status_message: Option<String>,
667 pub capacity_group: String,
668 pub desired_machines: u32,
669 pub assigned_machines: u32,
670 pub healthy_instances: u32,
671 pub unavailable_instances: u32,
672 pub command_supported: bool,
673 pub latest_update_timestamp: String,
674 pub daemon_instances: Vec<ManagedRuntimeUnitStatus>,
675 pub events: Vec<ManagedRuntimeEventSnapshot>,
676}
677
678#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
679#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
680#[serde(rename_all = "camelCase")]
681pub struct ManagedRuntimeUnitStatus {
682 pub replica_id: String,
683 pub name: String,
684 pub machine_id: Option<String>,
685 pub node_name: Option<String>,
686 pub ip: Option<String>,
687 pub ready: bool,
688 pub phase: Option<String>,
689 pub status: Option<String>,
690 pub reason: Option<String>,
691 pub message: Option<String>,
692 pub restart_count: Option<u32>,
693 pub waiting_reason: Option<String>,
694 pub terminated_reason: Option<String>,
695 pub metrics_healthy: Option<bool>,
696 pub metrics_status: Option<String>,
697 pub metrics_last_updated: Option<String>,
698 pub cpu: Option<MetricSample>,
699 pub memory: Option<MetricSample>,
700}
701
702#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
703#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
704#[serde(rename_all = "camelCase")]
705pub struct KubernetesDaemonHeartbeatData {
706 pub status: WorkloadHeartbeatStatus,
707 pub namespace: String,
708 pub name: String,
709 pub replicas: WorkloadReplicaStatus,
710 pub restarts: Option<u32>,
711 pub command_supported: bool,
712 pub cpu: Option<MetricSample>,
713 pub memory: Option<MetricSample>,
714 pub workload: Option<KubernetesWorkloadStatus>,
715 pub pods: Vec<KubernetesPodRuntimeUnitStatus>,
716 pub events: Vec<KubernetesEventSnapshot>,
717}
718
719#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
720#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
721#[serde(rename_all = "camelCase")]
722pub struct LocalDaemonHeartbeatData {
723 pub status: WorkloadHeartbeatStatus,
724 pub daemon_name: String,
725 pub runtime_id: String,
726 pub pid: Option<u32>,
727 pub command_supported: bool,
728 pub image_path_present: bool,
729 pub restart_count: Option<u32>,
730 pub exit_reason: Option<String>,
731 pub daemon_instance: Option<LocalRuntimeUnitStatus>,
732 pub events: Vec<LocalRuntimeEventSnapshot>,
733}
734
735#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
736#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
737#[serde(rename_all = "camelCase")]
738pub struct LocalRuntimeUnitStatus {
739 pub unit_id: String,
740 pub name: String,
741 pub kind: LocalRuntimeUnitKind,
742 pub ready: bool,
743 pub phase: Option<String>,
744 pub pid: Option<u32>,
745 pub restart_count: Option<u32>,
746 pub cpu: Option<MetricSample>,
747 pub memory: Option<MetricSample>,
748}
749
750#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
751#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
752#[serde(rename_all = "kebab-case")]
753pub enum LocalRuntimeUnitKind {
754 Container,
755 Process,
756 Daemon,
757}
758
759#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
760#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
761#[serde(rename_all = "camelCase")]
762pub enum KubernetesWorkloadKind {
763 Deployment,
764 StatefulSet,
765 DaemonSet,
766 ReplicaSet,
767 Pod,
768}
769
770#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
771#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
772#[serde(rename_all = "camelCase")]
773pub struct KubernetesWorkloadStatus {
774 pub desired_replicas: Option<u32>,
775 pub ready_replicas: Option<u32>,
776 pub available_replicas: Option<u32>,
777 pub updated_replicas: Option<u32>,
778 pub observed_generation: Option<i64>,
779 pub desired_generation: Option<i64>,
780 pub rollout_reason: Option<String>,
781 pub conditions: Vec<KubernetesWorkloadCondition>,
782}
783
784#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
785#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
786#[serde(rename_all = "camelCase")]
787pub struct KubernetesWorkloadCondition {
788 #[serde(rename = "type")]
789 pub condition_type: String,
790 pub status: String,
791 pub reason: Option<String>,
792 pub message: Option<String>,
793 pub last_transition_time: Option<DateTime<Utc>>,
794}
795
796#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
797#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
798#[serde(rename_all = "camelCase")]
799pub struct KubernetesPodRuntimeUnitStatus {
800 pub name: String,
801 pub uid: Option<String>,
802 pub phase: Option<String>,
803 pub ready: bool,
804 pub restart_count: u32,
805 pub waiting_reason: Option<String>,
806 pub terminated_reason: Option<String>,
807 pub node_name: Option<String>,
808 pub pod_ip: Option<String>,
809 pub owner_references: Vec<KubernetesOwnerReference>,
810 pub cpu: Option<MetricSample>,
811 pub memory: Option<MetricSample>,
812}
813
814#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
815#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
816#[serde(rename_all = "camelCase")]
817pub struct KubernetesOwnerReference {
818 pub kind: String,
819 pub name: String,
820 pub uid: String,
821 pub controller: bool,
822}
823
824#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
825#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
826#[serde(tag = "backend", rename_all = "camelCase")]
827pub enum ComputeClusterHeartbeatData {
828 Aws(AwsComputeClusterHeartbeatData),
829 Gcp(GcpComputeClusterHeartbeatData),
830 Azure(AzureComputeClusterHeartbeatData),
831 Local(LocalComputeClusterHeartbeatData),
832}
833
834#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
835#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
836#[serde(rename_all = "camelCase")]
837pub struct ComputeClusterHeartbeatStatus {
838 pub health: ObservedHealth,
839 pub lifecycle: ProviderLifecycleState,
840 pub message: Option<String>,
841 pub stale: bool,
842 pub partial: bool,
843 pub collection_issues: Vec<HeartbeatCollectionIssue>,
844}
845
846#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
847#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
848#[serde(rename_all = "camelCase")]
849pub struct LocalComputeClusterHeartbeatData {
850 pub status: ComputeClusterHeartbeatStatus,
851 pub nodes: ObservedCounts,
852 pub name: String,
853 pub host_identifier: Option<String>,
854 pub docker_available: bool,
855 pub docker_version: Option<String>,
856 pub docker_api_version: Option<String>,
857 pub docker_os: Option<String>,
858 pub docker_arch: Option<String>,
859 pub network_name: Option<String>,
860 pub network_available: bool,
861 pub tracked_containers: Option<u32>,
862 pub running_containers: Option<u32>,
863}
864
865#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
866#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
867#[serde(rename_all = "camelCase")]
868pub struct AwsComputeClusterHeartbeatData {
869 pub status: ComputeClusterHeartbeatStatus,
870 pub nodes: ObservedCounts,
871 pub cpu: Option<MetricSample>,
872 pub memory: Option<MetricSample>,
873 pub name: String,
874 pub region: Option<String>,
875 pub backend_cluster_id: Option<String>,
876 pub capacity_groups: Vec<ComputeCapacityGroupStatus>,
877 pub provider_fleets: Vec<ProviderFleetStatus>,
878}
879
880#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
881#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
882#[serde(rename_all = "camelCase")]
883pub struct GcpComputeClusterHeartbeatData {
884 pub status: ComputeClusterHeartbeatStatus,
885 pub nodes: ObservedCounts,
886 pub cpu: Option<MetricSample>,
887 pub memory: Option<MetricSample>,
888 pub name: String,
889 pub region: Option<String>,
890 pub backend_cluster_id: Option<String>,
891 pub capacity_groups: Vec<ComputeCapacityGroupStatus>,
892 pub provider_fleets: Vec<ProviderFleetStatus>,
893}
894
895#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
896#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
897#[serde(rename_all = "camelCase")]
898pub struct AzureComputeClusterHeartbeatData {
899 pub status: ComputeClusterHeartbeatStatus,
900 pub nodes: ObservedCounts,
901 pub cpu: Option<MetricSample>,
902 pub memory: Option<MetricSample>,
903 pub name: String,
904 pub region: Option<String>,
905 pub backend_cluster_id: Option<String>,
906 pub capacity_groups: Vec<ComputeCapacityGroupStatus>,
907 pub provider_fleets: Vec<ProviderFleetStatus>,
908}
909
910#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
911#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
912#[serde(rename_all = "camelCase")]
913pub struct ComputeCapacityGroupStatus {
914 pub group_id: String,
915 pub current_machines: u32,
916 pub desired_machines: u32,
917 pub min_machines: Option<u32>,
918 pub max_machines: Option<u32>,
919 pub instance_type: Option<String>,
920 pub recommendation: Option<ComputeCapacityRecommendation>,
921 pub capacity_blocker: Option<ComputeCapacityBlocker>,
922}
923
924#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
925#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
926#[serde(rename_all = "camelCase")]
927pub enum ComputeCapacityBlockerCategory {
928 Quota,
929 Capacity,
930 Allocation,
931 Other,
932}
933
934#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
935#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
936#[serde(rename_all = "camelCase")]
937pub struct ComputeCapacityBlocker {
938 pub category: ComputeCapacityBlockerCategory,
939 pub provider_code: Option<String>,
940 pub message: String,
941 pub provider_reference: Option<String>,
942 pub observed_at: DateTime<Utc>,
943}
944
945#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
946#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
947#[serde(rename_all = "camelCase")]
948pub struct ComputeCapacityRecommendation {
949 pub desired_machines: u32,
950 pub reason: Option<String>,
951 pub utilization: Option<MetricSample>,
952 pub unschedulable_replicas: Option<u32>,
953}
954
955#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
956#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
957#[serde(rename_all = "camelCase")]
958pub struct ProviderFleetStatus {
959 pub group_id: String,
960 pub provider_id: String,
961 pub location: Option<String>,
962 pub current_machines: u32,
963 pub desired_machines: u32,
964}
965
966#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
967#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
968#[serde(rename_all = "camelCase")]
969pub struct KubernetesClusterHeartbeatData {
970 pub status: WorkloadHeartbeatStatus,
971 pub node_counts: ObservedCounts,
972 pub pod_counts: ObservedCounts,
973 pub cpu: Option<MetricSample>,
974 pub memory: Option<MetricSample>,
975 pub name: String,
976 pub region: Option<String>,
977 pub namespace: Option<String>,
978 pub version: Option<String>,
979 #[serde(default, skip_serializing_if = "Vec::is_empty")]
980 pub node_statuses: Vec<KubernetesClusterNodeStatus>,
981 pub events: Vec<KubernetesEventSnapshot>,
982}
983
984#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
985#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
986#[serde(rename_all = "camelCase")]
987pub struct KubernetesClusterNodeStatus {
988 pub name: String,
989 pub uid: Option<String>,
990 pub ready: bool,
991 #[serde(default, skip_serializing_if = "Vec::is_empty")]
992 pub conditions: Vec<KubernetesNodeConditionStatus>,
993 pub roles: Vec<String>,
994 pub labels: BTreeMap<String, String>,
995 pub allocatable: KubernetesNodeResources,
996 pub capacity: KubernetesNodeResources,
997 pub usage: Option<KubernetesNodeUsage>,
998 pub kubelet_version: Option<String>,
999 pub container_runtime_version: Option<String>,
1000}
1001
1002#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1003#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1004#[serde(rename_all = "camelCase")]
1005pub struct KubernetesNodeConditionStatus {
1006 pub type_: String,
1007 pub status: String,
1008 pub reason: Option<String>,
1009 pub message: Option<String>,
1010}
1011
1012#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1013#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1014#[serde(rename_all = "camelCase")]
1015pub struct KubernetesNodeResources {
1016 pub cpu: Option<MetricSample>,
1017 pub memory: Option<MetricSample>,
1018 pub pods: Option<u64>,
1019}
1020
1021#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1022#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1023#[serde(rename_all = "camelCase")]
1024pub struct KubernetesNodeUsage {
1025 pub cpu: Option<MetricSample>,
1026 pub memory: Option<MetricSample>,
1027}
1028
1029#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1030#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1031#[serde(tag = "backend", rename_all = "camelCase")]
1032pub enum QueueHeartbeatData {
1033 AwsSqs(AwsSqsQueueHeartbeatData),
1034 GcpPubSub(GcpPubSubQueueHeartbeatData),
1035 AzureServiceBus(AzureServiceBusQueueHeartbeatData),
1036 Local(LocalQueueHeartbeatData),
1037}
1038
1039#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1040#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1041#[serde(rename_all = "camelCase")]
1042pub struct QueueHeartbeatStatus {
1043 pub health: ObservedHealth,
1044 pub lifecycle: ProviderLifecycleState,
1045 pub message: Option<String>,
1046 pub stale: bool,
1047 pub partial: bool,
1048 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1049}
1050
1051impl Default for QueueHeartbeatStatus {
1052 fn default() -> Self {
1053 Self {
1054 health: ObservedHealth::Unknown,
1055 lifecycle: ProviderLifecycleState::Unknown,
1056 message: None,
1057 stale: false,
1058 partial: false,
1059 collection_issues: vec![],
1060 }
1061 }
1062}
1063
1064#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1065#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1066#[serde(rename_all = "camelCase")]
1067pub struct LocalQueueHeartbeatData {
1068 pub status: QueueHeartbeatStatus,
1069 pub name: String,
1070 pub path: Option<String>,
1071 pub service_status: Option<String>,
1072}
1073
1074#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1075#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1076#[serde(rename_all = "camelCase")]
1077pub struct GcpPubSubQueueHeartbeatData {
1078 pub status: QueueHeartbeatStatus,
1079 pub topic_name: String,
1080 pub subscription_name: Option<String>,
1081 pub project_id: Option<String>,
1082 pub topic_full_name: Option<String>,
1083 pub subscription_full_name: Option<String>,
1084 pub endpoint: Option<String>,
1085 pub topic_labels: BTreeMap<String, String>,
1086 pub subscription_labels: BTreeMap<String, String>,
1087 pub message_storage_allowed_persistence_regions: Vec<String>,
1088 pub message_storage_enforce_in_transit: Option<bool>,
1089 pub kms_key_name: Option<String>,
1090 pub schema_name: Option<String>,
1091 pub schema_encoding: Option<String>,
1092 pub schema_first_revision_id: Option<String>,
1093 pub schema_last_revision_id: Option<String>,
1094 pub topic_message_retention_duration: Option<String>,
1095 pub topic_state: Option<String>,
1096 pub subscription_ack_deadline_seconds: Option<u32>,
1097 pub subscription_message_retention_duration: Option<String>,
1098 pub subscription_retain_acked_messages: Option<bool>,
1099 pub subscription_enable_message_ordering: Option<bool>,
1100 pub subscription_filter: Option<String>,
1101 pub subscription_detached: Option<bool>,
1102 pub subscription_state: Option<String>,
1103 pub subscription_push_config_present: Option<bool>,
1104 pub subscription_push_endpoint: Option<String>,
1105 pub subscription_push_attributes: BTreeMap<String, String>,
1106 pub subscription_push_oidc_service_account_email: Option<String>,
1107 pub subscription_push_oidc_audience: Option<String>,
1108 pub subscription_push_pubsub_wrapper_write_metadata: Option<bool>,
1109 pub subscription_push_no_wrapper_write_metadata: Option<bool>,
1110 pub subscription_dead_letter_topic: Option<String>,
1111 pub subscription_dead_letter_max_delivery_attempts: Option<u32>,
1112}
1113
1114#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1115#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1116#[serde(rename_all = "camelCase")]
1117pub struct AzureServiceBusQueueHeartbeatData {
1118 pub status: QueueHeartbeatStatus,
1119 pub name: String,
1120 pub namespace_name: String,
1121 pub resource_group: Option<String>,
1122 pub resource_id: Option<String>,
1123 pub endpoint: Option<String>,
1124 pub queue_status: Option<String>,
1125 pub lock_duration: Option<String>,
1126 pub max_delivery_count: Option<u32>,
1127 pub requires_duplicate_detection: Option<bool>,
1128 pub duplicate_detection_history_time_window: Option<String>,
1129 pub requires_session: Option<bool>,
1130 pub dead_lettering_on_message_expiration: Option<bool>,
1131 pub forward_dead_lettered_messages_to: Option<String>,
1132 pub forward_to: Option<String>,
1133 pub default_message_time_to_live: Option<String>,
1134 pub auto_delete_on_idle: Option<String>,
1135 pub enable_batched_operations: Option<bool>,
1136 pub enable_express: Option<bool>,
1137 pub enable_partitioning: Option<bool>,
1138 pub max_message_size_in_kilobytes: Option<u64>,
1139 pub max_size_in_megabytes: Option<u32>,
1140 pub message_count: Option<u64>,
1141 pub active_message_count: Option<u64>,
1142 pub dead_letter_message_count: Option<u64>,
1143 pub scheduled_message_count: Option<u64>,
1144 pub transfer_message_count: Option<u64>,
1145 pub transfer_dead_letter_message_count: Option<u64>,
1146 pub size_in_bytes: Option<u64>,
1147 pub accessed_at: Option<String>,
1148 pub created_at: Option<String>,
1149 pub updated_at: Option<String>,
1150}
1151
1152#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1153#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1154#[serde(rename_all = "camelCase")]
1155pub struct AwsSqsQueueHeartbeatData {
1156 pub status: QueueHeartbeatStatus,
1157 pub name: String,
1158 pub region: Option<String>,
1159 pub queue_url: Option<String>,
1160 pub queue_arn: Option<String>,
1161 pub visibility_timeout_seconds: Option<u32>,
1162 pub message_retention_period_seconds: Option<u32>,
1163 pub delay_seconds: Option<u32>,
1164 pub receive_message_wait_time_seconds: Option<u32>,
1165 pub maximum_message_size: Option<u32>,
1166 pub redrive_policy: Option<String>,
1167 pub redrive_allow_policy: Option<String>,
1168 pub fifo_queue: Option<bool>,
1169 pub content_based_deduplication: Option<bool>,
1170 pub deduplication_scope: Option<String>,
1171 pub fifo_throughput_limit: Option<String>,
1172 pub sse_enabled: Option<bool>,
1173 pub kms_master_key_id: Option<String>,
1174 pub kms_data_key_reuse_period_seconds: Option<u32>,
1175 pub sqs_managed_sse_enabled: Option<bool>,
1176 pub approximate_visible_messages: Option<u64>,
1177 pub approximate_in_flight_messages: Option<u64>,
1178 pub approximate_delayed_messages: Option<u64>,
1179 pub approximate_counts: bool,
1180}
1181
1182#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1183#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1184#[serde(tag = "backend", rename_all = "camelCase")]
1185pub enum KvHeartbeatData {
1186 AwsDynamoDb(AwsDynamoDbKvHeartbeatData),
1187 GcpFirestore(GcpFirestoreKvHeartbeatData),
1188 AzureTable(AzureTableKvHeartbeatData),
1189 Local(LocalKvHeartbeatData),
1190}
1191
1192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1193#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1194#[serde(rename_all = "camelCase")]
1195pub struct KvHeartbeatStatus {
1196 pub health: ObservedHealth,
1197 pub lifecycle: ProviderLifecycleState,
1198 pub message: Option<String>,
1199 pub stale: bool,
1200 pub partial: bool,
1201 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1202}
1203
1204impl Default for KvHeartbeatStatus {
1205 fn default() -> Self {
1206 Self {
1207 health: ObservedHealth::Unknown,
1208 lifecycle: ProviderLifecycleState::Unknown,
1209 message: None,
1210 stale: false,
1211 partial: false,
1212 collection_issues: vec![],
1213 }
1214 }
1215}
1216
1217#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1218#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1219#[serde(rename_all = "camelCase")]
1220pub struct AwsDynamoDbKvHeartbeatData {
1221 pub status: KvHeartbeatStatus,
1222 pub name: String,
1223 pub region: Option<String>,
1224 pub table_arn: Option<String>,
1225 pub table_status: Option<String>,
1226 pub billing_mode: Option<String>,
1227 pub key_schema: Vec<AwsDynamoDbKeySchemaElement>,
1228 pub global_secondary_index_count: Option<u32>,
1229 pub local_secondary_index_count: Option<u32>,
1230 pub item_count: Option<u64>,
1231 pub table_size_bytes: Option<u64>,
1232 pub stream_enabled: Option<bool>,
1233 pub stream_view_type: Option<String>,
1234 pub ttl_status: Option<String>,
1235 pub ttl_attribute_name: Option<String>,
1236 pub deletion_protection_enabled: Option<bool>,
1237 pub sse_status: Option<String>,
1238 pub sse_type: Option<String>,
1239 pub table_class: Option<String>,
1240 pub replica_count: Option<u32>,
1241 pub restore_in_progress: Option<bool>,
1242}
1243
1244#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1245#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1246#[serde(rename_all = "camelCase")]
1247pub struct AwsDynamoDbKeySchemaElement {
1248 pub attribute_name: String,
1249 pub key_type: String,
1250}
1251
1252#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1253#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1254#[serde(rename_all = "camelCase")]
1255pub struct GcpFirestoreKvHeartbeatData {
1256 pub status: KvHeartbeatStatus,
1257 pub database_name: String,
1258 pub project_id: Option<String>,
1259 pub endpoint: Option<String>,
1260 pub location_id: Option<String>,
1261 pub database_type: Option<String>,
1262 pub concurrency_mode: Option<String>,
1263 pub app_engine_integration_mode: Option<String>,
1264 pub delete_protection_state: Option<String>,
1265 pub point_in_time_recovery_enablement: Option<String>,
1266 pub version_retention_period: Option<String>,
1267 pub earliest_version_time: Option<String>,
1268 pub create_time: Option<String>,
1269 pub update_time: Option<String>,
1270 pub delete_time: Option<String>,
1271 pub database_edition: Option<String>,
1272 pub cmek_enabled: bool,
1273 pub source_info_present: bool,
1274}
1275
1276#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1277#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1278#[serde(rename_all = "camelCase")]
1279pub struct AzureTableKvHeartbeatData {
1280 pub status: KvHeartbeatStatus,
1281 pub table_name: String,
1282 pub storage_account_name: String,
1283 pub resource_group: Option<String>,
1284 pub endpoint: Option<String>,
1285 pub storage_account_resource_id: Option<String>,
1286 pub storage_account_location: Option<String>,
1287 pub storage_account_kind: Option<String>,
1288 pub storage_account_provisioning_state: Option<String>,
1289 pub storage_account_primary_status: Option<String>,
1290 pub table_exists: bool,
1291 pub signed_identifier_count: Option<u32>,
1292}
1293
1294#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1295#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1296#[serde(rename_all = "camelCase")]
1297pub struct LocalKvHeartbeatData {
1298 pub status: KvHeartbeatStatus,
1299 pub name: String,
1300 pub path: String,
1301 pub path_exists: bool,
1302 pub is_directory: Option<bool>,
1303 pub cloud_metadata_supported: bool,
1304}
1305
1306#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1307#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1308#[serde(tag = "backend", rename_all = "camelCase")]
1309pub enum VaultHeartbeatData {
1310 AwsParameterStore(AwsParameterStoreVaultHeartbeatData),
1311 GcpSecretManager(GcpSecretManagerVaultHeartbeatData),
1312 AzureKeyVault(AzureKeyVaultHeartbeatData),
1313 KubernetesSecret(KubernetesSecretVaultHeartbeatData),
1314 Local(LocalVaultHeartbeatData),
1315}
1316
1317#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1318#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1319#[serde(rename_all = "camelCase")]
1320pub struct VaultHeartbeatStatus {
1321 pub health: ObservedHealth,
1322 pub lifecycle: ProviderLifecycleState,
1323 pub message: Option<String>,
1324 pub stale: bool,
1325 pub partial: bool,
1326 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1327}
1328
1329impl Default for VaultHeartbeatStatus {
1330 fn default() -> Self {
1331 Self {
1332 health: ObservedHealth::Healthy,
1333 lifecycle: ProviderLifecycleState::Running,
1334 message: None,
1335 stale: false,
1336 partial: false,
1337 collection_issues: vec![],
1338 }
1339 }
1340}
1341
1342#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1343#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1344#[serde(rename_all = "camelCase")]
1345pub struct AwsParameterStoreVaultHeartbeatData {
1346 pub status: VaultHeartbeatStatus,
1347 pub account_id: String,
1348 pub region: String,
1349 pub prefix: String,
1350 pub parameter_metadata_sampled: bool,
1351 pub sampled_parameter_count: Option<u32>,
1352 pub sampled_secure_string_count: Option<u32>,
1353 pub sampled_string_count: Option<u32>,
1354 pub sampled_string_list_count: Option<u32>,
1355 pub sampled_advanced_tier_count: Option<u32>,
1356 pub sampled_kms_key_metadata_present_count: Option<u32>,
1357 pub latest_modified_at: Option<DateTime<Utc>>,
1358 pub has_more_parameters: Option<bool>,
1359}
1360
1361#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1362#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1363#[serde(rename_all = "camelCase")]
1364pub struct GcpSecretManagerVaultHeartbeatData {
1365 pub status: VaultHeartbeatStatus,
1366 pub project_id: String,
1367 pub location: String,
1368 pub prefix: String,
1369 pub secret_metadata_listed: bool,
1370}
1371
1372#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1373#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1374#[serde(rename_all = "camelCase")]
1375pub struct AzureKeyVaultHeartbeatData {
1376 pub status: VaultHeartbeatStatus,
1377 pub name: String,
1378 pub resource_group: Option<String>,
1379 pub resource_id: Option<String>,
1380 pub location: Option<String>,
1381 pub vault_uri: Option<String>,
1382 pub provisioning_state: Option<String>,
1383 pub sku_family: Option<String>,
1384 pub sku_name: Option<String>,
1385 pub soft_delete_enabled: bool,
1386 pub soft_delete_retention_days: i32,
1387 pub purge_protection_enabled: Option<bool>,
1388 pub rbac_authorization_enabled: bool,
1389 pub public_network_access: String,
1390 pub access_policy_count: u32,
1391 pub private_endpoint_connection_count: u32,
1392 pub secret_metadata_listed: bool,
1393}
1394
1395#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1396#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1397#[serde(rename_all = "camelCase")]
1398pub struct KubernetesSecretVaultHeartbeatData {
1399 pub status: VaultHeartbeatStatus,
1400 pub namespace: String,
1401 pub prefix: String,
1402 pub secret_metadata_listed: bool,
1403}
1404
1405#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1406#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1407#[serde(rename_all = "camelCase")]
1408pub struct LocalVaultHeartbeatData {
1409 pub status: VaultHeartbeatStatus,
1410 pub path: String,
1411 pub path_exists: bool,
1412 pub is_directory: Option<bool>,
1413 pub readonly: Option<bool>,
1414 pub modified_at: Option<DateTime<Utc>>,
1415 pub secret_metadata_listed: bool,
1416}
1417
1418#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1419#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1420#[serde(tag = "backend", rename_all = "camelCase")]
1421pub enum ServiceAccountHeartbeatData {
1422 AwsIamRole(AwsIamRoleServiceAccountHeartbeatData),
1423 GcpServiceAccount(GcpServiceAccountHeartbeatData),
1424 AzureManagedIdentity(AzureManagedIdentityServiceAccountHeartbeatData),
1425 Local(LocalServiceAccountHeartbeatData),
1426}
1427
1428#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1429#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1430#[serde(rename_all = "camelCase")]
1431pub struct ServiceAccountHeartbeatStatus {
1432 pub health: ObservedHealth,
1433 pub lifecycle: ProviderLifecycleState,
1434 pub message: Option<String>,
1435 pub stale: bool,
1436 pub partial: bool,
1437 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1438}
1439
1440#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1441#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1442#[serde(rename_all = "camelCase")]
1443pub struct AwsIamRoleServiceAccountHeartbeatData {
1444 pub status: ServiceAccountHeartbeatStatus,
1445 pub role_name: String,
1446 pub role_arn: String,
1447 pub role_id: String,
1448 pub path: String,
1449 pub create_date: String,
1450 pub description: Option<String>,
1451 pub max_session_duration: Option<i32>,
1452 pub assume_role_policy_present: bool,
1453 pub permissions_boundary_type: Option<String>,
1454 pub permissions_boundary_arn: Option<String>,
1455 pub tag_count: u32,
1456 pub managed_tag_count: u32,
1457 pub attached_policy_count: u32,
1458 pub attached_policy_names: Vec<String>,
1459 pub inline_policy_count: u32,
1460 pub inline_policy_names: Vec<String>,
1461 pub stack_permissions_applied: bool,
1462 pub last_used_date: Option<String>,
1463 pub last_used_region: Option<String>,
1464}
1465
1466#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1467#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1468#[serde(rename_all = "camelCase")]
1469pub struct GcpServiceAccountHeartbeatData {
1470 pub status: ServiceAccountHeartbeatStatus,
1471 pub name: Option<String>,
1472 pub project_id: Option<String>,
1473 pub unique_id: Option<String>,
1474 pub email: String,
1475 pub display_name: Option<String>,
1476 pub description: Option<String>,
1477 pub oauth2_client_id: Option<String>,
1478 pub disabled: Option<bool>,
1479 pub etag: Option<String>,
1480 pub project_binding_count: u32,
1481 pub project_roles: Vec<String>,
1482 pub service_account_binding_count: u32,
1483 pub service_account_roles: Vec<String>,
1484}
1485
1486#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1487#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1488#[serde(rename_all = "camelCase")]
1489pub struct AzureManagedIdentityServiceAccountHeartbeatData {
1490 pub status: ServiceAccountHeartbeatStatus,
1491 pub name: String,
1492 pub resource_id: String,
1493 pub resource_group: String,
1494 pub location: String,
1495 pub type_: Option<String>,
1496 pub client_id: Option<String>,
1497 pub principal_id: Option<String>,
1498 pub tenant_id: Option<String>,
1499 pub isolation_scope: Option<String>,
1500 pub managed_tag_count: u32,
1501 pub role_assignment_count: u32,
1502 pub role_assignment_ids: Vec<String>,
1503 pub custom_role_definition_count: u32,
1504 pub custom_role_definition_ids: Vec<String>,
1505 pub stack_permissions_applied: bool,
1506}
1507
1508#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1509#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1510#[serde(rename_all = "camelCase")]
1511pub struct LocalServiceAccountHeartbeatData {
1512 pub status: ServiceAccountHeartbeatStatus,
1513 pub identity: String,
1514 pub configured: bool,
1515}
1516
1517#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1518#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1519#[serde(tag = "backend", rename_all = "camelCase")]
1520pub enum NetworkHeartbeatData {
1521 AwsVpc(AwsVpcNetworkHeartbeatData),
1522 GcpVpc(GcpVpcNetworkHeartbeatData),
1523 AzureVnet(AzureVnetNetworkHeartbeatData),
1524}
1525
1526#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1527#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1528#[serde(rename_all = "camelCase")]
1529pub struct NetworkHeartbeatStatus {
1530 pub health: ObservedHealth,
1531 pub lifecycle: ProviderLifecycleState,
1532 pub message: Option<String>,
1533 pub stale: bool,
1534 pub partial: bool,
1535 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1536}
1537
1538#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1539#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1540#[serde(rename_all = "camelCase")]
1541pub struct AwsVpcNetworkHeartbeatData {
1542 pub status: NetworkHeartbeatStatus,
1543 pub vpc_id: Option<String>,
1544 pub vpc_state: Option<String>,
1545 pub cidr_block: Option<String>,
1546 pub public_subnet_ids: Vec<String>,
1547 pub private_subnet_ids: Vec<String>,
1548 pub availability_zones: Vec<String>,
1549 pub internet_gateway_id: Option<String>,
1550 pub nat_gateway_id: Option<String>,
1551 pub route_table_count: u32,
1552 pub security_group_id: Option<String>,
1553 pub is_byo_vpc: bool,
1554}
1555
1556#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1557#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1558#[serde(rename_all = "camelCase")]
1559pub struct GcpVpcNetworkHeartbeatData {
1560 pub status: NetworkHeartbeatStatus,
1561 pub network_name: Option<String>,
1562 pub network_self_link: Option<String>,
1563 pub subnetwork_name: Option<String>,
1564 pub subnetwork_self_link: Option<String>,
1565 pub region: Option<String>,
1566 pub cidr_block: Option<String>,
1567 pub router_name: Option<String>,
1568 pub cloud_nat_name: Option<String>,
1569 pub firewall_name: Option<String>,
1570 pub is_byo_vpc: bool,
1571}
1572
1573#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1574#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1575#[serde(rename_all = "camelCase")]
1576pub struct AzureVnetNetworkHeartbeatData {
1577 pub status: NetworkHeartbeatStatus,
1578 pub vnet_name: Option<String>,
1579 pub vnet_resource_id: Option<String>,
1580 pub resource_group: Option<String>,
1581 pub location: Option<String>,
1582 pub cidr_block: Option<String>,
1583 pub public_subnet_name: Option<String>,
1584 pub private_subnet_name: Option<String>,
1585 pub application_gateway_subnet_name: Option<String>,
1586 pub nat_gateway_id: Option<String>,
1587 pub public_ip_id: Option<String>,
1588 pub nsg_id: Option<String>,
1589 pub is_byo_vnet: bool,
1590 pub last_byo_vnet_verification_error_code: Option<String>,
1591}
1592
1593#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1594#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1595#[serde(tag = "backend", rename_all = "camelCase")]
1596pub enum RemoteStackManagementHeartbeatData {
1597 AwsIamRole(AwsRemoteStackManagementHeartbeatData),
1598 GcpServiceAccount(GcpRemoteStackManagementHeartbeatData),
1599 AzureManagedIdentity(AzureRemoteStackManagementHeartbeatData),
1600}
1601
1602#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1603#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1604#[serde(rename_all = "camelCase")]
1605pub struct RemoteStackManagementHeartbeatStatus {
1606 pub health: ObservedHealth,
1607 pub lifecycle: ProviderLifecycleState,
1608 pub message: Option<String>,
1609 pub stale: bool,
1610 pub partial: bool,
1611 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1612}
1613
1614#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1615#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1616#[serde(rename_all = "camelCase")]
1617pub struct AwsRemoteStackManagementHeartbeatData {
1618 pub status: RemoteStackManagementHeartbeatStatus,
1619 pub role_name: Option<String>,
1620 pub role_arn: Option<String>,
1621 pub management_permissions_applied: bool,
1622}
1623
1624#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1625#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1626#[serde(rename_all = "camelCase")]
1627pub struct GcpRemoteStackManagementHeartbeatData {
1628 pub status: RemoteStackManagementHeartbeatStatus,
1629 pub service_account_email: Option<String>,
1630 pub service_account_unique_id: Option<String>,
1631 pub role_bound: bool,
1632 pub impersonation_granted: bool,
1633}
1634
1635#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1636#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1637#[serde(rename_all = "camelCase")]
1638pub struct AzureRemoteStackManagementHeartbeatData {
1639 pub status: RemoteStackManagementHeartbeatStatus,
1640 pub uami_resource_id: Option<String>,
1641 pub uami_client_id: Option<String>,
1642 pub uami_principal_id: Option<String>,
1643 pub tenant_id: Option<String>,
1644 pub fic_name: Option<String>,
1645 pub role_definition_id: Option<String>,
1646 pub role_assignment_ids: Vec<String>,
1647}
1648
1649#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1650#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1651#[serde(tag = "backend", rename_all = "camelCase")]
1652pub enum ArtifactRegistryHeartbeatData {
1653 AwsEcr(AwsEcrArtifactRegistryHeartbeatData),
1654 GcpArtifactRegistry(GcpArtifactRegistryHeartbeatData),
1655 AzureContainerRegistry(AzureContainerRegistryHeartbeatData),
1656 Local(LocalArtifactRegistryHeartbeatData),
1657}
1658
1659#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1660#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1661#[serde(rename_all = "camelCase")]
1662pub struct ArtifactRegistryHeartbeatStatus {
1663 pub health: ObservedHealth,
1664 pub lifecycle: ProviderLifecycleState,
1665 pub message: Option<String>,
1666 pub stale: bool,
1667 pub partial: bool,
1668 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1669}
1670
1671#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1672#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1673#[serde(rename_all = "camelCase")]
1674pub struct AwsEcrArtifactRegistryHeartbeatData {
1675 pub status: ArtifactRegistryHeartbeatStatus,
1676 pub registry_id: String,
1677 pub region: String,
1678 pub registry_uri: String,
1679 pub repository_prefix: String,
1680 pub pull_role_arn: Option<String>,
1681 pub push_role_arn: Option<String>,
1682 pub repository_count: u32,
1683 pub repositories_truncated: bool,
1684 pub repositories: Vec<AwsEcrRepositoryHeartbeatData>,
1685}
1686
1687#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1688#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1689#[serde(rename_all = "camelCase")]
1690pub struct AwsEcrRepositoryHeartbeatData {
1691 pub repository_arn: String,
1692 pub registry_id: String,
1693 pub repository_name: String,
1694 pub repository_uri: String,
1695 pub created_at: f64,
1696 pub image_tag_mutability: Option<String>,
1697 pub scan_on_push: Option<bool>,
1698 pub encryption_type: Option<String>,
1699 pub kms_key_present: bool,
1700}
1701
1702#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1703#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1704#[serde(rename_all = "camelCase")]
1705pub struct GcpArtifactRegistryHeartbeatData {
1706 pub status: ArtifactRegistryHeartbeatStatus,
1707 pub project_id: String,
1708 pub location: String,
1709 pub repository_id: String,
1710 pub name: Option<String>,
1711 pub format: Option<String>,
1712 pub mode: Option<String>,
1713 pub description: Option<String>,
1714 pub label_count: u32,
1715 pub cleanup_policy_count: u32,
1716 pub cleanup_policy_dry_run: Option<bool>,
1717 pub kms_key_name_present: bool,
1718 pub size_bytes: Option<String>,
1719 pub satisfies_pzs: Option<bool>,
1720 pub create_time: Option<String>,
1721 pub update_time: Option<String>,
1722 pub iam_policy_etag_present: bool,
1723 pub iam_binding_count: u32,
1724 pub iam_roles: Vec<String>,
1725 pub pull_service_account_email: Option<String>,
1726 pub push_service_account_email: Option<String>,
1727}
1728
1729#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1730#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1731#[serde(rename_all = "camelCase")]
1732pub struct AzureContainerRegistryHeartbeatData {
1733 pub status: ArtifactRegistryHeartbeatStatus,
1734 pub name: String,
1735 pub resource_id: Option<String>,
1736 pub resource_group: String,
1737 pub location: String,
1738 pub type_: Option<String>,
1739 pub login_server: Option<String>,
1740 pub sku_name: String,
1741 pub sku_tier: Option<String>,
1742 pub provisioning_state: Option<String>,
1743 pub admin_user_enabled: bool,
1744 pub anonymous_pull_enabled: bool,
1745 pub public_network_access: String,
1746 pub network_rule_bypass_options: String,
1747 pub network_rule_default_action: Option<String>,
1748 pub ip_rule_count: u32,
1749 pub encryption_status: Option<String>,
1750 pub encryption_key_vault_uri_present: bool,
1751 pub encryption_key_identifier_present: bool,
1752 pub policies_present: bool,
1753 pub policy_count: u32,
1754 pub private_endpoint_connection_count: u32,
1755 pub data_endpoint_enabled: Option<bool>,
1756 pub data_endpoint_host_names: Vec<String>,
1757 pub zone_redundancy: String,
1758 pub creation_date: Option<String>,
1759 pub managed_tag_count: u32,
1760}
1761
1762#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1763#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1764#[serde(rename_all = "camelCase")]
1765pub struct LocalArtifactRegistryHeartbeatData {
1766 pub status: ArtifactRegistryHeartbeatStatus,
1767 pub registry_url: String,
1768 pub reachable: bool,
1769}
1770
1771#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1772#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1773#[serde(tag = "backend", rename_all = "camelCase")]
1774pub enum BuildHeartbeatData {
1775 AwsCodeBuild(AwsCodeBuildHeartbeatData),
1776 GcpCloudBuild(GcpCloudBuildHeartbeatData),
1777 AzureContainerApps(AzureContainerAppsBuildHeartbeatData),
1778 KubernetesJob(KubernetesBuildHeartbeatData),
1779}
1780
1781#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1782#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1783#[serde(rename_all = "camelCase")]
1784pub struct BuildHeartbeatStatus {
1785 pub health: ObservedHealth,
1786 pub lifecycle: ProviderLifecycleState,
1787 pub message: Option<String>,
1788 pub stale: bool,
1789 pub partial: bool,
1790 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1791}
1792
1793#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1794#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1795#[serde(rename_all = "camelCase")]
1796pub struct AwsCodeBuildHeartbeatData {
1797 pub status: BuildHeartbeatStatus,
1798 pub project_name: String,
1799 pub project_arn: Option<String>,
1800 pub description: Option<String>,
1801 pub source_type: Option<String>,
1802 pub artifacts_type: Option<String>,
1803 pub artifacts_encryption_disabled: Option<bool>,
1804 pub environment_type: Option<String>,
1805 pub environment_image: Option<String>,
1806 pub compute_type: Option<String>,
1807 pub image_pull_credentials_type: Option<String>,
1808 pub privileged_mode: Option<bool>,
1809 pub environment_variable_count: u32,
1810 pub service_role_present: bool,
1811 pub encryption_key_present: bool,
1812 pub cloud_watch_logs_status: Option<String>,
1813 pub s3_logs_status: Option<String>,
1814 pub timeout_in_minutes: Option<i32>,
1815 pub queued_timeout_in_minutes: Option<i32>,
1816 pub created: Option<f64>,
1817 pub last_modified: Option<f64>,
1818}
1819
1820#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1821#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1822#[serde(rename_all = "camelCase")]
1823pub struct GcpCloudBuildHeartbeatData {
1824 pub status: BuildHeartbeatStatus,
1825 pub project_id: String,
1826 pub location: String,
1827 pub build_config_id: String,
1828 pub service_account: Option<String>,
1829 pub environment_variable_count: u32,
1830}
1831
1832#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1833#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1834#[serde(rename_all = "camelCase")]
1835pub struct AzureContainerAppsBuildHeartbeatData {
1836 pub status: BuildHeartbeatStatus,
1837 pub managed_environment_id: String,
1838 pub resource_group_name: String,
1839 pub managed_identity_id: Option<String>,
1840 pub resource_prefix: Option<String>,
1841 pub environment_variable_count: u32,
1842}
1843
1844#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1845#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1846#[serde(rename_all = "camelCase")]
1847pub struct KubernetesBuildHeartbeatData {
1848 pub status: BuildHeartbeatStatus,
1849 pub job_name: String,
1850 pub namespace: String,
1851 pub active: Option<i32>,
1852 pub succeeded: Option<i32>,
1853 pub failed: Option<i32>,
1854 pub start_time: Option<DateTime<Utc>>,
1855 pub completion_time: Option<DateTime<Utc>>,
1856 pub condition_count: u32,
1857 pub image_digest: Option<String>,
1858 pub events: Vec<KubernetesEventSnapshot>,
1859}
1860
1861#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1862#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1863#[serde(tag = "backend", rename_all = "camelCase")]
1864pub enum ServiceActivationHeartbeatData {
1865 GcpServiceUsage(GcpServiceUsageActivationHeartbeatData),
1866 AzureResourceProvider(AzureResourceProviderActivationHeartbeatData),
1867}
1868
1869#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1870#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1871#[serde(rename_all = "camelCase")]
1872pub struct ServiceActivationHeartbeatStatus {
1873 pub health: ObservedHealth,
1874 pub lifecycle: ProviderLifecycleState,
1875 pub message: Option<String>,
1876 pub stale: bool,
1877 pub partial: bool,
1878 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1879}
1880
1881impl Default for ServiceActivationHeartbeatStatus {
1882 fn default() -> Self {
1883 Self {
1884 health: ObservedHealth::Healthy,
1885 lifecycle: ProviderLifecycleState::Running,
1886 message: None,
1887 stale: false,
1888 partial: false,
1889 collection_issues: vec![],
1890 }
1891 }
1892}
1893
1894#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1895#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1896#[serde(rename_all = "camelCase")]
1897pub struct GcpServiceUsageActivationHeartbeatData {
1898 pub status: ServiceActivationHeartbeatStatus,
1899 pub project_id: String,
1900 pub service_name: String,
1901 pub service_resource_name: Option<String>,
1902 pub title: Option<String>,
1903 pub state: Option<String>,
1904 pub enabled: bool,
1905 pub last_operation_name: Option<String>,
1906}
1907
1908#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1909#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1910#[serde(rename_all = "camelCase")]
1911pub struct AzureResourceProviderActivationHeartbeatData {
1912 pub status: ServiceActivationHeartbeatStatus,
1913 pub namespace: String,
1914 pub provider_id: Option<String>,
1915 pub registration_state: Option<String>,
1916 pub registration_policy: Option<String>,
1917 pub resource_type_count: u32,
1918 pub registered: bool,
1919}
1920
1921#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1922#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1923#[serde(rename_all = "camelCase")]
1924pub struct AzureResourceGroupHeartbeatData {
1925 pub status: AzureResourceGroupHeartbeatStatus,
1926 pub name: String,
1927 pub resource_id: Option<String>,
1928 pub location: Option<String>,
1929 pub provisioning_state: Option<String>,
1930 pub managed_tags: BTreeMap<String, String>,
1931}
1932
1933#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1934#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1935#[serde(rename_all = "camelCase")]
1936pub struct AzureResourceGroupHeartbeatStatus {
1937 pub health: ObservedHealth,
1938 pub lifecycle: ProviderLifecycleState,
1939 pub message: Option<String>,
1940 pub stale: bool,
1941 pub partial: bool,
1942 pub collection_issues: Vec<HeartbeatCollectionIssue>,
1943}
1944
1945impl Default for AzureResourceGroupHeartbeatStatus {
1946 fn default() -> Self {
1947 Self {
1948 health: ObservedHealth::Healthy,
1949 lifecycle: ProviderLifecycleState::Running,
1950 message: None,
1951 stale: false,
1952 partial: false,
1953 collection_issues: vec![],
1954 }
1955 }
1956}
1957
1958#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1959#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1960#[serde(rename_all = "camelCase")]
1961pub struct AzureStorageAccountHeartbeatData {
1962 pub status: StorageHeartbeatStatus,
1963 pub name: String,
1964 pub resource_id: Option<String>,
1965 pub resource_group: Option<String>,
1966 pub location: Option<String>,
1967 pub kind: Option<String>,
1968 pub sku_name: Option<String>,
1969 pub sku_tier: Option<String>,
1970 pub provisioning_state: Option<String>,
1971 pub primary_endpoints: AzureStorageAccountEndpoints,
1972 pub secondary_endpoints: AzureStorageAccountEndpoints,
1973 pub public_network_access: Option<String>,
1974 pub allow_blob_public_access: Option<bool>,
1975 pub allow_shared_key_access: Option<bool>,
1976 pub minimum_tls_version: Option<String>,
1977 pub supports_https_traffic_only: Option<bool>,
1978 pub encryption_key_source: Option<String>,
1979 pub require_infrastructure_encryption: Option<bool>,
1980 pub network_default_action: Option<String>,
1981 pub network_bypass: Option<String>,
1982 pub network_ip_rule_count: Option<u32>,
1983 pub network_virtual_network_rule_count: Option<u32>,
1984 pub network_resource_access_rule_count: Option<u32>,
1985}
1986
1987#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
1988#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
1989#[serde(rename_all = "camelCase")]
1990pub struct AzureStorageAccountEndpoints {
1991 pub blob: Option<String>,
1992 pub dfs: Option<String>,
1993 pub file: Option<String>,
1994 pub queue: Option<String>,
1995 pub table: Option<String>,
1996 pub web: Option<String>,
1997}
1998
1999#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2000#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2001#[serde(rename_all = "camelCase")]
2002pub struct AzureContainerAppsEnvironmentHeartbeatData {
2003 pub status: AzureContainerAppsEnvironmentHeartbeatStatus,
2004 pub name: String,
2005 pub resource_id: Option<String>,
2006 pub resource_group: Option<String>,
2007 pub location: Option<String>,
2008 pub kind: Option<String>,
2009 pub provisioning_state: Option<String>,
2010 pub default_domain: Option<String>,
2011 pub static_ip: Option<String>,
2012 pub custom_domain_verification_id: Option<String>,
2013 pub infrastructure_resource_group: Option<String>,
2014 pub event_stream_endpoint: Option<String>,
2015 pub zone_redundant: Option<bool>,
2016 pub workload_profile_count: u32,
2017 pub workload_profiles: Vec<AzureContainerAppsEnvironmentWorkloadProfile>,
2018}
2019
2020#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2021#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2022#[serde(rename_all = "camelCase")]
2023pub struct AzureContainerAppsEnvironmentHeartbeatStatus {
2024 pub health: ObservedHealth,
2025 pub lifecycle: ProviderLifecycleState,
2026 pub message: Option<String>,
2027 pub stale: bool,
2028 pub partial: bool,
2029 pub collection_issues: Vec<HeartbeatCollectionIssue>,
2030}
2031
2032#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2033#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2034#[serde(rename_all = "camelCase")]
2035pub struct AzureContainerAppsEnvironmentWorkloadProfile {
2036 pub name: String,
2037 pub workload_profile_type: String,
2038 pub minimum_count: Option<i32>,
2039 pub maximum_count: Option<i32>,
2040}
2041
2042#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2043#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2044#[serde(rename_all = "camelCase")]
2045pub struct AzureServiceBusNamespaceHeartbeatData {
2046 pub status: QueueHeartbeatStatus,
2047 pub name: String,
2048 pub resource_id: Option<String>,
2049 pub resource_group: Option<String>,
2050 pub location: Option<String>,
2051 pub sku_name: Option<String>,
2052 pub sku_tier: Option<String>,
2053 pub sku_capacity: Option<i32>,
2054 pub namespace_status: Option<String>,
2055 pub provisioning_state: Option<String>,
2056 pub service_bus_endpoint: Option<String>,
2057 pub metric_id: Option<String>,
2058 pub public_network_access: Option<String>,
2059 pub disable_local_auth: Option<bool>,
2060 pub minimum_tls_version: Option<String>,
2061 pub premium_messaging_partitions: Option<i32>,
2062 pub private_endpoint_connection_count: u32,
2063 pub zone_redundant: Option<bool>,
2064 pub created_at: Option<String>,
2065 pub updated_at: Option<String>,
2066}
2067
2068#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2069#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
2070#[serde(rename_all = "camelCase")]
2071pub struct NamedResourceDetail {
2072 pub name: String,
2073 pub region: Option<String>,
2074}
2075
2076#[cfg(test)]
2077mod tests {
2078 use super::*;
2079 use chrono::TimeZone as _;
2080 use serde_json::json;
2081
2082 fn observed_at() -> DateTime<Utc> {
2083 Utc.with_ymd_and_hms(2026, 5, 28, 10, 30, 0).unwrap()
2084 }
2085
2086 fn workload_status() -> WorkloadHeartbeatStatus {
2087 WorkloadHeartbeatStatus {
2088 health: ObservedHealth::Healthy,
2089 lifecycle: ProviderLifecycleState::Running,
2090 message: None,
2091 stale: false,
2092 partial: false,
2093 collection_issues: vec![],
2094 }
2095 }
2096
2097 fn workload_replicas() -> WorkloadReplicaStatus {
2098 WorkloadReplicaStatus {
2099 desired: Some(2),
2100 current: Some(2),
2101 ready: Some(1),
2102 available: Some(1),
2103 updated: Some(2),
2104 misscheduled: None,
2105 }
2106 }
2107
2108 fn heartbeat(data: ResourceHeartbeatData, resource_type: &str) -> ResourceHeartbeat {
2109 ResourceHeartbeat {
2110 deployment_id: Some("dep_123".to_string()),
2111 resource_id: "api".to_string(),
2112 resource_type: ResourceType::from(resource_type),
2113 controller_platform: Platform::Kubernetes,
2114 backend: HeartbeatBackend::Kubernetes,
2115 observed_at: observed_at(),
2116 data,
2117 raw: vec![RawHeartbeatSnippet {
2118 source: "kubernetes/apps/v1/deployments/api".to_string(),
2119 format: RawHeartbeatSnippetFormat::Json,
2120 collected_at: observed_at(),
2121 body: r#"{"readyReplicas":1}"#.to_string(),
2122 truncated: false,
2123 }],
2124 }
2125 }
2126
2127 #[test]
2128 fn container_heartbeat_serializes_resource_first_data() {
2129 let heartbeat = heartbeat(
2130 ResourceHeartbeatData::Container(ContainerHeartbeatData::Kubernetes(
2131 KubernetesContainerHeartbeatData {
2132 status: workload_status(),
2133 namespace: "default".to_string(),
2134 name: "api".to_string(),
2135 workload_kind: KubernetesWorkloadKind::Deployment,
2136 replicas: workload_replicas(),
2137 restarts: Some(1),
2138 cpu: Some(MetricSample {
2139 value: 0.5,
2140 unit: MetricUnit::Cores,
2141 }),
2142 memory: None,
2143 workload: None,
2144 pods: vec![],
2145 events: vec![],
2146 },
2147 )),
2148 "container",
2149 );
2150
2151 let value = serde_json::to_value(&heartbeat).unwrap();
2152
2153 assert_eq!(value["resourceType"], "container");
2154 assert_eq!(value["data"]["resourceType"], "container");
2155 assert_eq!(value["data"]["data"]["backend"], "kubernetes");
2156 assert_eq!(value["raw"][0]["body"], r#"{"readyReplicas":1}"#);
2157 assert!(value.get("collection").is_none());
2158 assert!(value["data"]["data"].get("summary").is_none());
2159 assert!(value["data"]["data"].get("detail").is_none());
2160 }
2161
2162 #[test]
2163 fn representative_workload_data_has_stable_tags() {
2164 let daemon = serde_json::to_value(ResourceHeartbeatData::Daemon(
2165 DaemonHeartbeatData::Kubernetes(KubernetesDaemonHeartbeatData {
2166 status: workload_status(),
2167 namespace: "default".to_string(),
2168 name: "agent".to_string(),
2169 replicas: workload_replicas(),
2170 restarts: Some(0),
2171 command_supported: true,
2172 cpu: None,
2173 memory: None,
2174 workload: None,
2175 pods: vec![],
2176 events: vec![],
2177 }),
2178 ))
2179 .unwrap();
2180 let worker = serde_json::to_value(ResourceHeartbeatData::Worker(
2181 WorkerHeartbeatData::AwsLambda(AwsLambdaWorkerHeartbeatData {
2182 status: workload_status(),
2183 function_name: "handler".to_string(),
2184 runtime: Some("nodejs22.x".to_string()),
2185 package_type: None,
2186 memory_size_mb: None,
2187 timeout_seconds: None,
2188 version: None,
2189 revision_id: None,
2190 last_modified: None,
2191 state: None,
2192 state_reason: None,
2193 state_reason_code: None,
2194 last_update_status: None,
2195 last_update_status_reason: None,
2196 last_update_status_reason_code: None,
2197 code_sha256: None,
2198 layer_count: 0,
2199 function_url_auth_type: None,
2200 function_url_cors_present: false,
2201 trigger_count: 0,
2202 }),
2203 ))
2204 .unwrap();
2205
2206 assert_eq!(daemon["resourceType"], "daemon");
2207 assert_eq!(daemon["data"]["backend"], "kubernetes");
2208 assert_eq!(worker["resourceType"], "worker");
2209 assert_eq!(worker["data"]["backend"], "awsLambda");
2210 }
2211
2212 #[test]
2213 fn representative_cluster_and_data_variants_have_optional_counts() {
2214 let cluster = serde_json::to_value(ResourceHeartbeatData::KubernetesCluster(
2215 KubernetesClusterHeartbeatData {
2216 status: WorkloadHeartbeatStatus {
2217 health: ObservedHealth::Healthy,
2218 lifecycle: ProviderLifecycleState::Running,
2219 message: None,
2220 stale: false,
2221 partial: false,
2222 collection_issues: vec![],
2223 },
2224 node_counts: ObservedCounts {
2225 desired: Some(3),
2226 current: Some(3),
2227 ready: None,
2228 },
2229 pod_counts: ObservedCounts {
2230 desired: None,
2231 current: Some(12),
2232 ready: Some(11),
2233 },
2234 cpu: None,
2235 memory: None,
2236 name: "prod".to_string(),
2237 region: Some("us-east-1".to_string()),
2238 namespace: None,
2239 version: Some("1.33".to_string()),
2240 node_statuses: vec![],
2241 events: vec![],
2242 },
2243 ))
2244 .unwrap();
2245 let queue = serde_json::to_value(ResourceHeartbeatData::Queue(QueueHeartbeatData::AwsSqs(
2246 AwsSqsQueueHeartbeatData {
2247 status: QueueHeartbeatStatus {
2248 health: ObservedHealth::Healthy,
2249 lifecycle: ProviderLifecycleState::Running,
2250 message: None,
2251 stale: false,
2252 partial: false,
2253 collection_issues: vec![],
2254 },
2255 name: "jobs".to_string(),
2256 region: Some("us-east-1".to_string()),
2257 queue_url: Some("https://sqs.us-east-1.amazonaws.com/123/jobs".to_string()),
2258 queue_arn: Some("arn:aws:sqs:us-east-1:123:jobs".to_string()),
2259 visibility_timeout_seconds: Some(30),
2260 message_retention_period_seconds: Some(345600),
2261 delay_seconds: Some(0),
2262 receive_message_wait_time_seconds: Some(0),
2263 maximum_message_size: Some(262144),
2264 redrive_policy: None,
2265 redrive_allow_policy: None,
2266 fifo_queue: Some(false),
2267 content_based_deduplication: None,
2268 deduplication_scope: None,
2269 fifo_throughput_limit: None,
2270 sse_enabled: Some(false),
2271 kms_master_key_id: None,
2272 kms_data_key_reuse_period_seconds: None,
2273 sqs_managed_sse_enabled: Some(false),
2274 approximate_visible_messages: Some(42),
2275 approximate_in_flight_messages: Some(1),
2276 approximate_delayed_messages: Some(0),
2277 approximate_counts: true,
2278 },
2279 )))
2280 .unwrap();
2281 let storage = serde_json::to_value(ResourceHeartbeatData::Storage(
2282 StorageHeartbeatData::AwsS3(AwsS3StorageHeartbeatData {
2283 status: StorageHeartbeatStatus {
2284 health: ObservedHealth::Healthy,
2285 lifecycle: ProviderLifecycleState::Running,
2286 message: None,
2287 stale: false,
2288 partial: false,
2289 collection_issues: vec![],
2290 },
2291 name: "assets".to_string(),
2292 region: Some("us-east-1".to_string()),
2293 bucket_location: Some("us-east-1".to_string()),
2294 versioning_status: Some("Enabled".to_string()),
2295 versioning_enabled: Some(true),
2296 lifecycle_present: false,
2297 lifecycle_rule_count: Some(0),
2298 encryption_config_present: true,
2299 encryption_enabled: Some(true),
2300 public_access_block_present: true,
2301 block_public_acls: Some(true),
2302 ignore_public_acls: Some(true),
2303 block_public_policy: Some(true),
2304 restrict_public_buckets: Some(true),
2305 bucket_policy_present: Some(false),
2306 bucket_acl_present: Some(true),
2307 }),
2308 ))
2309 .unwrap();
2310 let gcp_storage = serde_json::to_value(ResourceHeartbeatData::Storage(
2311 StorageHeartbeatData::GcpCloudStorage(GcpCloudStorageHeartbeatData {
2312 status: StorageHeartbeatStatus {
2313 health: ObservedHealth::Healthy,
2314 lifecycle: ProviderLifecycleState::Running,
2315 message: None,
2316 stale: false,
2317 partial: false,
2318 collection_issues: vec![],
2319 },
2320 name: "assets".to_string(),
2321 bucket_id: Some("project/assets".to_string()),
2322 location: Some("US".to_string()),
2323 location_type: Some("multi-region".to_string()),
2324 storage_class: Some("STANDARD".to_string()),
2325 versioning_enabled: Some(true),
2326 lifecycle_present: false,
2327 lifecycle_rule_count: Some(0),
2328 retention_policy_effective_time: None,
2329 retention_policy_is_locked: None,
2330 retention_period: None,
2331 soft_delete_retention_duration_seconds: None,
2332 soft_delete_effective_time: None,
2333 uniform_bucket_level_access_enabled: Some(true),
2334 uniform_bucket_level_access_locked_time: None,
2335 public_access_prevention: Some("enforced".to_string()),
2336 encryption_config_present: true,
2337 default_kms_key_name: Some(
2338 "projects/p/locations/l/keyRings/r/cryptoKeys/k".to_string(),
2339 ),
2340 }),
2341 ))
2342 .unwrap();
2343 let kv = serde_json::to_value(ResourceHeartbeatData::Kv(KvHeartbeatData::AwsDynamoDb(
2344 AwsDynamoDbKvHeartbeatData {
2345 status: KvHeartbeatStatus {
2346 health: ObservedHealth::Healthy,
2347 lifecycle: ProviderLifecycleState::Running,
2348 message: None,
2349 stale: false,
2350 partial: false,
2351 collection_issues: vec![],
2352 },
2353 name: "state".to_string(),
2354 region: Some("us-east-1".to_string()),
2355 table_arn: None,
2356 table_status: Some("ACTIVE".to_string()),
2357 billing_mode: Some("PAY_PER_REQUEST".to_string()),
2358 key_schema: vec![AwsDynamoDbKeySchemaElement {
2359 attribute_name: "pk".to_string(),
2360 key_type: "HASH".to_string(),
2361 }],
2362 global_secondary_index_count: Some(0),
2363 local_secondary_index_count: Some(0),
2364 item_count: None,
2365 table_size_bytes: None,
2366 stream_enabled: Some(false),
2367 stream_view_type: None,
2368 ttl_status: Some("ENABLED".to_string()),
2369 ttl_attribute_name: Some("ttl".to_string()),
2370 deletion_protection_enabled: Some(false),
2371 sse_status: Some("ENABLED".to_string()),
2372 sse_type: Some("KMS".to_string()),
2373 table_class: None,
2374 replica_count: Some(0),
2375 restore_in_progress: None,
2376 },
2377 )))
2378 .unwrap();
2379
2380 assert_eq!(cluster["resourceType"], "kubernetes-cluster");
2381 assert!(cluster["data"].get("summary").is_none());
2382 assert!(cluster["data"].get("detail").is_none());
2383 assert_eq!(cluster["data"]["name"], "prod");
2384 assert_eq!(queue["data"]["backend"], "awsSqs");
2385 assert_eq!(queue["data"]["approximateVisibleMessages"], 42);
2386 assert!(queue["data"].get("summary").is_none());
2387 assert_eq!(storage["data"]["backend"], "awsS3");
2388 assert!(storage["data"].get("summary").is_none());
2389 assert_eq!(gcp_storage["data"]["backend"], "gcpCloudStorage");
2390 assert_eq!(gcp_storage["data"]["publicAccessPrevention"], "enforced");
2391 assert_eq!(kv["data"]["backend"], "awsDynamoDb");
2392 assert!(kv["data"].get("summary").is_none());
2393 assert_eq!(kv["data"]["itemCount"], json!(null));
2394 }
2395}