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