alien_core/
setup_package.rs1use crate::{
2 ownership_policy_for_resource_type, ErrorData, Key, ManagementPermissions, Platform,
3 ResourceEntry, Result, Sandbox, SetupManagement, Stack, Storage,
4};
5use alien_error::AlienError;
6
7pub fn validate_automatic_setup_resources(
10 stack: &Stack,
11 platform: Platform,
12 management: SetupManagement,
13) -> Result<()> {
14 if management == SetupManagement::Automatic
15 && matches!(platform, Platform::Aws | Platform::Gcp | Platform::Azure)
16 {
17 let unsupported = |resource_type: &str, resource_id: &str| {
18 AlienError::new(ErrorData::AutomaticSetupResourceUnsupported {
19 resource_type: resource_type.to_string(),
20 resource_id: resource_id.to_string(),
21 platform,
22 })
23 };
24 match stack.management() {
25 ManagementPermissions::Override(_) => {
27 return Err(unsupported(
28 "management permission override",
29 "permissions.management",
30 ));
31 }
32 ManagementPermissions::Extend(profile) if platform == Platform::Aws => {
35 if let Some(scope) = profile.0.keys().find(|scope| scope.as_str() != "*") {
36 return Err(unsupported("resource-scoped management permission", scope));
37 }
38 }
39 _ => {}
40 }
41 for (id, entry) in stack.resources() {
42 if let Some(resource_type) = automatic_setup_unsupported_resource(entry, platform) {
43 return Err(unsupported(&resource_type, id));
44 }
45 }
46 }
47 if management == SetupManagement::Automatic && platform == Platform::Azure {
48 for (id, entry) in stack.resources() {
49 if entry.config.downcast_ref::<Sandbox>().is_some() {
50 return Err(AlienError::new(ErrorData::SandboxCapabilityUnsupported {
51 capability: format!(
52 "automatic infrastructure management for sandbox '{id}'; use manual setup to create and import its sandbox group"
53 ),
54 platform: platform.to_string(),
55 }));
56 }
57 }
58 }
59 Ok(())
60}
61
62fn automatic_setup_unsupported_resource(
66 entry: &ResourceEntry,
67 platform: Platform,
68) -> Option<String> {
69 if entry.config.downcast_ref::<Key>().is_some() {
70 return Some("key".to_string());
71 }
72 let resource_type = entry.config.resource_type();
73 if matches!(
75 resource_type.as_ref(),
76 "email" | "experimental/aws-opensearch" | "kubernetes-cluster"
77 ) {
78 return Some(resource_type.as_ref().to_string());
79 }
80 if platform == Platform::Aws
83 && entry
84 .config
85 .downcast_ref::<Storage>()
86 .is_some_and(|storage| !storage.cors_allowed_origins.is_empty())
87 {
88 return Some("storage with CORS origins".to_string());
89 }
90 None
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
96pub enum SetupConfigurationProfile {
97 Standard,
98 Advanced,
99}
100
101pub fn emits_package_scaffolding(entry: &ResourceEntry, management: SetupManagement) -> bool {
105 let resource_type = entry.config.resource_type();
106 if management == SetupManagement::Automatic {
107 is_automatic_setup_package_resource_type(resource_type.as_ref())
108 } else {
109 ownership_policy_for_resource_type(resource_type.as_ref())
110 .emits_setup_scaffolding(entry.lifecycle)
111 }
112}
113
114pub fn is_automatic_setup_package_resource_type(resource_type: &str) -> bool {
118 matches!(
119 resource_type,
120 "remote-stack-management" | "vault" | "azure_resource_group" | "service_activation"
121 )
122}