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