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