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