use crate::{
ownership_policy_for_resource_type, ErrorData, Key, ManagementPermissions, Platform,
ResourceEntry, Result, Sandbox, SetupManagement, Stack, Storage,
};
use alien_error::AlienError;
pub fn validate_automatic_setup_resources(
stack: &Stack,
platform: Platform,
management: SetupManagement,
) -> Result<()> {
if management == SetupManagement::Automatic
&& matches!(platform, Platform::Aws | Platform::Gcp | Platform::Azure)
{
let unsupported = |resource_type: &str, resource_id: &str| {
AlienError::new(ErrorData::AutomaticSetupResourceUnsupported {
resource_type: resource_type.to_string(),
resource_id: resource_id.to_string(),
platform,
})
};
match stack.management() {
ManagementPermissions::Override(_) => {
return Err(unsupported(
"management permission override",
"permissions.management",
));
}
ManagementPermissions::Extend(profile) if platform == Platform::Aws => {
if let Some(scope) = profile.0.keys().find(|scope| scope.as_str() != "*") {
return Err(unsupported("resource-scoped management permission", scope));
}
}
_ => {}
}
for (id, entry) in stack.resources() {
if let Some(resource_type) = automatic_setup_unsupported_resource(entry, platform) {
return Err(unsupported(&resource_type, id));
}
}
}
if management == SetupManagement::Automatic && platform == Platform::Azure {
for (id, entry) in stack.resources() {
if entry.config.downcast_ref::<Sandbox>().is_some() {
return Err(AlienError::new(ErrorData::SandboxCapabilityUnsupported {
capability: format!(
"automatic infrastructure management for sandbox '{id}'; use manual setup to create and import its sandbox group"
),
platform: platform.to_string(),
}));
}
}
}
Ok(())
}
fn automatic_setup_unsupported_resource(
entry: &ResourceEntry,
platform: Platform,
) -> Option<String> {
if entry.config.downcast_ref::<Key>().is_some() {
return Some("key".to_string());
}
let resource_type = entry.config.resource_type();
if matches!(
resource_type.as_ref(),
"email" | "experimental/aws-opensearch" | "kubernetes-cluster"
) {
return Some(resource_type.as_ref().to_string());
}
if platform == Platform::Aws
&& entry
.config
.downcast_ref::<Storage>()
.is_some_and(|storage| !storage.cors_allowed_origins.is_empty())
{
return Some("storage with CORS origins".to_string());
}
None
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SetupConfigurationProfile {
Standard,
Advanced,
}
pub fn emits_package_scaffolding(entry: &ResourceEntry, management: SetupManagement) -> bool {
let resource_type = entry.config.resource_type();
if management == SetupManagement::Automatic {
is_automatic_setup_package_resource_type(resource_type.as_ref())
} else {
ownership_policy_for_resource_type(resource_type.as_ref())
.emits_setup_scaffolding(entry.lifecycle)
}
}
pub fn is_automatic_setup_package_resource_type(resource_type: &str) -> bool {
matches!(
resource_type,
"remote-stack-management" | "vault" | "azure_resource_group" | "service_activation"
)
}