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    AwsEmailDkimTokenImportData, AwsEmailDomainImportData, AwsEmailImportData, AwsKvImportData,
13    AwsNetworkImportData, AwsOpenSearchImportData, AwsPostgresImportData, AwsQueueImportData,
14    AwsRemoteStackManagementImportData, AwsServiceAccountImportData, AwsStorageImportData,
15    AwsVaultImportData, AwsWorkerImportData,
16};
17pub use azure::{
18    AzureArtifactRegistryImportData, AzureBuildImportData, AzureComputeClusterImportData,
19    AzureContainerAppsEnvironmentImportData, AzureFlexibleServerPostgresImportData,
20    AzureKvImportData, AzureNetworkImportData, AzureQueueImportData,
21    AzureRemoteStackManagementImportData, AzureResourceGroupImportData,
22    AzureServiceAccountImportData, AzureServiceActivationImportData,
23    AzureServiceBusNamespaceImportData, AzureStorageAccountImportData, AzureStorageImportData,
24    AzureVaultImportData, AzureWorkerImportData,
25};
26pub use gcp::{
27    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            (
66                "aws_artifact_registry",
67                schema::<AwsArtifactRegistryImportData>(),
68            ),
69            ("aws_build", schema::<AwsBuildImportData>()),
70            (
71                "aws_compute_cluster",
72                schema::<AwsComputeClusterImportData>(),
73            ),
74            ("aws_email", schema::<AwsEmailImportData>()),
75            ("aws_function", schema::<AwsWorkerImportData>()),
76            ("aws_kv", schema::<AwsKvImportData>()),
77            ("aws_network", schema::<AwsNetworkImportData>()),
78            ("aws_open_search", schema::<AwsOpenSearchImportData>()),
79            ("aws_postgres", schema::<AwsPostgresImportData>()),
80            ("aws_queue", schema::<AwsQueueImportData>()),
81            (
82                "aws_remote_stack_management",
83                schema::<AwsRemoteStackManagementImportData>(),
84            ),
85            (
86                "aws_service_account",
87                schema::<AwsServiceAccountImportData>(),
88            ),
89            ("aws_storage", schema::<AwsStorageImportData>()),
90            ("aws_vault", schema::<AwsVaultImportData>()),
91            (
92                "azure_artifact_registry",
93                schema::<AzureArtifactRegistryImportData>(),
94            ),
95            ("azure_build", schema::<AzureBuildImportData>()),
96            (
97                "azure_container_apps_environment",
98                schema::<AzureContainerAppsEnvironmentImportData>(),
99            ),
100            (
101                "azure_compute_cluster",
102                schema::<AzureComputeClusterImportData>(),
103            ),
104            ("azure_function", schema::<AzureWorkerImportData>()),
105            ("azure_kv", schema::<AzureKvImportData>()),
106            ("azure_network", schema::<AzureNetworkImportData>()),
107            (
108                "azure_postgres",
109                schema::<AzureFlexibleServerPostgresImportData>(),
110            ),
111            ("azure_queue", schema::<AzureQueueImportData>()),
112            (
113                "azure_remote_stack_management",
114                schema::<AzureRemoteStackManagementImportData>(),
115            ),
116            (
117                "azure_resource_group",
118                schema::<AzureResourceGroupImportData>(),
119            ),
120            (
121                "azure_service_account",
122                schema::<AzureServiceAccountImportData>(),
123            ),
124            (
125                "azure_service_activation",
126                schema::<AzureServiceActivationImportData>(),
127            ),
128            (
129                "azure_service_bus_namespace",
130                schema::<AzureServiceBusNamespaceImportData>(),
131            ),
132            ("azure_storage", schema::<AzureStorageImportData>()),
133            (
134                "azure_storage_account",
135                schema::<AzureStorageAccountImportData>(),
136            ),
137            ("azure_vault", schema::<AzureVaultImportData>()),
138            (
139                "gcp_artifact_registry",
140                schema::<GcpArtifactRegistryImportData>(),
141            ),
142            ("gcp_build", schema::<GcpBuildImportData>()),
143            (
144                "gcp_compute_cluster",
145                schema::<GcpComputeClusterImportData>(),
146            ),
147            ("gcp_function", schema::<GcpWorkerImportData>()),
148            ("gcp_kv", schema::<GcpKvImportData>()),
149            ("gcp_network", schema::<GcpNetworkImportData>()),
150            ("gcp_postgres", schema::<GcpPostgresImportData>()),
151            ("gcp_queue", schema::<GcpQueueImportData>()),
152            (
153                "gcp_remote_stack_management",
154                schema::<GcpRemoteStackManagementImportData>(),
155            ),
156            (
157                "kubernetes_cluster",
158                schema::<KubernetesClusterImportData>(),
159            ),
160            (
161                "gcp_service_account",
162                schema::<GcpServiceAccountImportData>(),
163            ),
164            (
165                "gcp_service_activation",
166                schema::<GcpServiceActivationImportData>(),
167            ),
168            ("gcp_storage", schema::<GcpStorageImportData>()),
169            ("gcp_vault", schema::<GcpVaultImportData>()),
170        ]);
171
172        insta::assert_json_snapshot!("import_data_schemas", schemas);
173    }
174}
175
176#[cfg(test)]
177mod tests {
178    use super::*;
179    use serde_json::json;
180
181    #[test]
182    fn aws_import_data_accepts_cloudformation_string_booleans() {
183        let network: AwsNetworkImportData = serde_json::from_value(json!({
184            "vpcId": "vpc-123",
185            "cidrBlock": null,
186            "internetGatewayId": null,
187            "natGatewayId": null,
188            "eipAllocationId": null,
189            "publicSubnetIds": ["subnet-public"],
190            "privateSubnetIds": ["subnet-private"],
191            "publicRouteTableId": null,
192            "privateRouteTableId": null,
193            "securityGroupId": "sg-123",
194            "availabilityZones": [],
195            "isByoVpc": "true",
196        }))
197        .expect("network import data should parse");
198        assert!(network.is_byo_vpc);
199
200        let remote_stack_management: AwsRemoteStackManagementImportData =
201            serde_json::from_value(json!({
202                "roleName": "alien-manager",
203                "roleArn": "arn:aws:iam::123456789012:role/alien-manager",
204                "managementPermissionsApplied": "true",
205            }))
206            .expect("remote stack management import data should parse");
207        assert!(remote_stack_management.management_permissions_applied);
208
209        let service_account: AwsServiceAccountImportData = serde_json::from_value(json!({
210            "roleName": "alien-worker",
211            "roleArn": "arn:aws:iam::123456789012:role/alien-worker",
212            "stackPermissionsApplied": "false",
213        }))
214        .expect("service account import data should parse");
215        assert!(!service_account.stack_permissions_applied);
216    }
217}