pub mod bootstrap;
pub mod credentials;
use greentic_deploy_spec::CapabilitySlot;
use semver::VersionReq;
use super::slot::EnvPackHandler;
use crate::tool_check::ToolCheck;
pub use credentials::{AwsDeployerCredentials, AwsValidatorClient};
#[derive(Debug, Default)]
pub struct AwsEcsDeployerHandler {
creds: AwsDeployerCredentials,
}
impl AwsEcsDeployerHandler {
pub const DESCRIPTOR_PATH: &'static str = "greentic.deployer.aws-ecs";
pub const VERSION_REQ: &'static str = ">=1.0.0-dev, <2.0.0";
pub fn with_client(client: std::sync::Arc<dyn AwsValidatorClient>) -> Self {
Self {
creds: AwsDeployerCredentials::with_client(client),
}
}
}
impl EnvPackHandler for AwsEcsDeployerHandler {
fn slot(&self) -> CapabilitySlot {
CapabilitySlot::Deployer
}
fn descriptor_path(&self) -> &str {
Self::DESCRIPTOR_PATH
}
fn supported_versions(&self) -> VersionReq {
Self::VERSION_REQ
.parse()
.expect("aws-ecs version-req is valid (guarded by tests)")
}
fn preflight(&self) -> Vec<ToolCheck> {
Vec::new()
}
fn deployer_credentials(&self) -> Option<&dyn crate::credentials::DeployerCredentials> {
Some(&self.creds)
}
fn wizard_qaspec_yaml(&self) -> Option<&'static str> {
Some(include_str!("wizard.qaspec.yaml"))
}
}
#[cfg(test)]
mod tests {
use super::*;
use greentic_deploy_spec::PackDescriptor;
#[test]
fn handler_serves_deployer_slot_with_aws_ecs_path() {
let h = AwsEcsDeployerHandler::default();
assert_eq!(h.slot(), CapabilitySlot::Deployer);
assert_eq!(h.descriptor_path(), "greentic.deployer.aws-ecs");
let _ = h.supported_versions();
}
#[test]
fn version_req_accepts_ga_and_dev_releases() {
let h = AwsEcsDeployerHandler::default();
let req = h.supported_versions();
let ga = PackDescriptor::try_new("greentic.deployer.aws-ecs@1.0.0").unwrap();
assert!(req.matches(&ga.version().0), "{req} must accept 1.0.0");
let dev = PackDescriptor::try_new("greentic.deployer.aws-ecs@1.0.0-dev.1").unwrap();
assert!(
req.matches(&dev.version().0),
"{req} must accept dev pre-release"
);
let next_major = PackDescriptor::try_new("greentic.deployer.aws-ecs@2.0.0").unwrap();
assert!(
!req.matches(&next_major.version().0),
"{req} must reject 2.0.0 (breaking bump)"
);
}
#[test]
fn exposes_credentials_contract() {
let h = AwsEcsDeployerHandler::default();
let creds = h
.deployer_credentials()
.expect("aws-ecs handler must expose credentials");
assert!(creds.requires_credentials_material());
}
#[test]
fn wizard_qaspec_yaml_pins_id_and_requires_region() {
let yaml = AwsEcsDeployerHandler::default()
.wizard_qaspec_yaml()
.expect("aws-ecs handler ships a wizard QASpec");
let spec: qa_spec::FormSpec =
serde_yaml_bw::from_str(yaml).expect("wizard.qaspec.yaml parses as FormSpec");
assert_eq!(spec.id, "greentic.deployer.aws-ecs.wizard");
assert!(
spec.questions.iter().any(|q| q.id == "region"),
"aws-ecs wizard must collect the AWS region (no sensible default)",
);
}
}