1use 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}