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