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