Skip to main content

alien_core/import/data/
mod.rs

1//! Typed ImportData payloads by cloud and resource.
2
3use serde::{Deserialize, Deserializer};
4
5pub mod aws;
6pub mod azure;
7pub mod gcp;
8pub mod kubernetes_cluster;
9
10pub use aws::{
11    AwsArtifactRegistryImportData, AwsBuildImportData, AwsComputeClusterImportData,
12    AwsKvImportData, AwsNetworkImportData, AwsPostgresImportData, AwsQueueImportData,
13    AwsRemoteStackManagementImportData, AwsServiceAccountImportData, AwsStorageImportData,
14    AwsVaultImportData, AwsWorkerImportData,
15};
16pub use azure::{
17    AzureArtifactRegistryImportData, AzureBuildImportData, AzureComputeClusterImportData,
18    AzureContainerAppsEnvironmentImportData, AzureFlexibleServerPostgresImportData,
19    AzureKvImportData, AzureNetworkImportData, AzureQueueImportData,
20    AzureRemoteStackManagementImportData, AzureResourceGroupImportData,
21    AzureServiceAccountImportData, AzureServiceActivationImportData,
22    AzureServiceBusNamespaceImportData, AzureStorageAccountImportData, AzureStorageImportData,
23    AzureVaultImportData, AzureWorkerImportData,
24};
25pub use gcp::{
26    GcpArtifactRegistryImportData, GcpBuildImportData, GcpComputeClusterImportData,
27    GcpKvImportData, GcpNetworkImportData, GcpPostgresImportData, GcpQueueImportData,
28    GcpRemoteStackManagementImportData, GcpServiceAccountImportData,
29    GcpServiceActivationImportData, GcpStorageImportData, GcpVaultImportData, GcpWorkerImportData,
30};
31pub use kubernetes_cluster::{
32    AzureApplicationGatewayForContainersBootstrap, KubernetesClusterImportData,
33};
34
35pub(crate) fn deserialize_bool_from_bool_or_string<'de, D>(
36    deserializer: D,
37) -> Result<bool, D::Error>
38where
39    D: Deserializer<'de>,
40{
41    let value = serde_json::Value::deserialize(deserializer)?;
42    match value {
43        serde_json::Value::Bool(value) => Ok(value),
44        serde_json::Value::String(value) if value.eq_ignore_ascii_case("true") => Ok(true),
45        serde_json::Value::String(value) if value.eq_ignore_ascii_case("false") => Ok(false),
46        other => Err(serde::de::Error::custom(format!(
47            "expected boolean or boolean string, got {other}"
48        ))),
49    }
50}
51
52#[cfg(all(test, feature = "jsonschema"))]
53mod schema_snapshots {
54    use super::*;
55    use indexmap::IndexMap;
56
57    fn schema<T: schemars::JsonSchema>() -> serde_json::Value {
58        serde_json::to_value(schemars::schema_for!(T)).expect("schema should serialize")
59    }
60
61    #[test]
62    fn import_data_schema_snapshot() {
63        let schemas = IndexMap::from([
64            (
65                "aws_artifact_registry",
66                schema::<AwsArtifactRegistryImportData>(),
67            ),
68            ("aws_build", schema::<AwsBuildImportData>()),
69            (
70                "aws_compute_cluster",
71                schema::<AwsComputeClusterImportData>(),
72            ),
73            ("aws_function", schema::<AwsWorkerImportData>()),
74            ("aws_kv", schema::<AwsKvImportData>()),
75            ("aws_network", schema::<AwsNetworkImportData>()),
76            ("aws_postgres", schema::<AwsPostgresImportData>()),
77            ("aws_queue", schema::<AwsQueueImportData>()),
78            (
79                "aws_remote_stack_management",
80                schema::<AwsRemoteStackManagementImportData>(),
81            ),
82            (
83                "aws_service_account",
84                schema::<AwsServiceAccountImportData>(),
85            ),
86            ("aws_storage", schema::<AwsStorageImportData>()),
87            ("aws_vault", schema::<AwsVaultImportData>()),
88            (
89                "azure_artifact_registry",
90                schema::<AzureArtifactRegistryImportData>(),
91            ),
92            ("azure_build", schema::<AzureBuildImportData>()),
93            (
94                "azure_container_apps_environment",
95                schema::<AzureContainerAppsEnvironmentImportData>(),
96            ),
97            (
98                "azure_compute_cluster",
99                schema::<AzureComputeClusterImportData>(),
100            ),
101            ("azure_function", schema::<AzureWorkerImportData>()),
102            ("azure_kv", schema::<AzureKvImportData>()),
103            ("azure_network", schema::<AzureNetworkImportData>()),
104            (
105                "azure_postgres",
106                schema::<AzureFlexibleServerPostgresImportData>(),
107            ),
108            ("azure_queue", schema::<AzureQueueImportData>()),
109            (
110                "azure_remote_stack_management",
111                schema::<AzureRemoteStackManagementImportData>(),
112            ),
113            (
114                "azure_resource_group",
115                schema::<AzureResourceGroupImportData>(),
116            ),
117            (
118                "azure_service_account",
119                schema::<AzureServiceAccountImportData>(),
120            ),
121            (
122                "azure_service_activation",
123                schema::<AzureServiceActivationImportData>(),
124            ),
125            (
126                "azure_service_bus_namespace",
127                schema::<AzureServiceBusNamespaceImportData>(),
128            ),
129            ("azure_storage", schema::<AzureStorageImportData>()),
130            (
131                "azure_storage_account",
132                schema::<AzureStorageAccountImportData>(),
133            ),
134            ("azure_vault", schema::<AzureVaultImportData>()),
135            (
136                "gcp_artifact_registry",
137                schema::<GcpArtifactRegistryImportData>(),
138            ),
139            ("gcp_build", schema::<GcpBuildImportData>()),
140            (
141                "gcp_compute_cluster",
142                schema::<GcpComputeClusterImportData>(),
143            ),
144            ("gcp_function", schema::<GcpWorkerImportData>()),
145            ("gcp_kv", schema::<GcpKvImportData>()),
146            ("gcp_network", schema::<GcpNetworkImportData>()),
147            ("gcp_postgres", schema::<GcpPostgresImportData>()),
148            ("gcp_queue", schema::<GcpQueueImportData>()),
149            (
150                "gcp_remote_stack_management",
151                schema::<GcpRemoteStackManagementImportData>(),
152            ),
153            (
154                "kubernetes_cluster",
155                schema::<KubernetesClusterImportData>(),
156            ),
157            (
158                "gcp_service_account",
159                schema::<GcpServiceAccountImportData>(),
160            ),
161            (
162                "gcp_service_activation",
163                schema::<GcpServiceActivationImportData>(),
164            ),
165            ("gcp_storage", schema::<GcpStorageImportData>()),
166            ("gcp_vault", schema::<GcpVaultImportData>()),
167        ]);
168
169        insta::assert_json_snapshot!("import_data_schemas", schemas);
170    }
171}
172
173#[cfg(test)]
174mod tests {
175    use super::*;
176    use serde_json::json;
177
178    #[test]
179    fn aws_import_data_accepts_cloudformation_string_booleans() {
180        let network: AwsNetworkImportData = serde_json::from_value(json!({
181            "vpcId": "vpc-123",
182            "cidrBlock": null,
183            "internetGatewayId": null,
184            "natGatewayId": null,
185            "eipAllocationId": null,
186            "publicSubnetIds": ["subnet-public"],
187            "privateSubnetIds": ["subnet-private"],
188            "publicRouteTableId": null,
189            "privateRouteTableId": null,
190            "securityGroupId": "sg-123",
191            "availabilityZones": [],
192            "isByoVpc": "true",
193        }))
194        .expect("network import data should parse");
195        assert!(network.is_byo_vpc);
196
197        let remote_stack_management: AwsRemoteStackManagementImportData =
198            serde_json::from_value(json!({
199                "roleName": "alien-manager",
200                "roleArn": "arn:aws:iam::123456789012:role/alien-manager",
201                "managementPermissionsApplied": "true",
202            }))
203            .expect("remote stack management import data should parse");
204        assert!(remote_stack_management.management_permissions_applied);
205
206        let service_account: AwsServiceAccountImportData = serde_json::from_value(json!({
207            "roleName": "alien-worker",
208            "roleArn": "arn:aws:iam::123456789012:role/alien-worker",
209            "stackPermissionsApplied": "false",
210        }))
211        .expect("service account import data should parse");
212        assert!(!service_account.stack_permissions_applied);
213    }
214}