use crate::error::{ApiForgeError, Result};
use crate::integrations::aws::AwsClient;
use crate::steps::{Step, StepContext, StepOutput};
use async_trait::async_trait;
pub struct CloudFrontInvalidateStep;
impl Default for CloudFrontInvalidateStep {
fn default() -> Self {
Self::new()
}
}
impl CloudFrontInvalidateStep {
pub fn new() -> Self {
Self
}
async fn get_aws_client(ctx: &StepContext) -> Result<AwsClient> {
if let Some(ref profile) = ctx.config.aws.profile {
AwsClient::with_profile(&ctx.config.aws.region, profile).await
} else {
AwsClient::new(&ctx.config.aws.region).await
}
}
}
#[async_trait]
impl Step for CloudFrontInvalidateStep {
fn name(&self) -> &str {
"cloudfront-invalidate"
}
fn description(&self) -> &str {
"Invalidate CloudFront cache paths"
}
async fn validate(&self, ctx: &StepContext) -> Result<()> {
let cf =
ctx.config.cloudfront.as_ref().ok_or_else(|| {
ApiForgeError::Config("CloudFront configuration missing".to_string())
})?;
if cf.distribution_id.is_empty() {
return Err(ApiForgeError::Config(
"cloudfront.distribution_id cannot be empty".to_string(),
));
}
if ctx.dry_run {
return Ok(());
}
let aws = Self::get_aws_client(ctx).await?;
aws.get_caller_identity().await?;
Ok(())
}
async fn execute(&self, ctx: &StepContext) -> Result<StepOutput> {
let cf =
ctx.config.cloudfront.as_ref().ok_or_else(|| {
ApiForgeError::Config("CloudFront configuration missing".to_string())
})?;
ctx.report_progress(&format!(
"cloudfront-invalidate: requesting invalidation for {} path(s)",
cf.paths.len()
));
let aws = Self::get_aws_client(ctx).await?;
let invalidation_id = aws
.create_cloudfront_invalidation(&cf.distribution_id, &cf.paths)
.await?;
Ok(StepOutput::ok(format!(
"Created invalidation {} on distribution {} ({} path(s))",
invalidation_id,
cf.distribution_id,
cf.paths.len()
)))
}
async fn dry_run(&self, ctx: &StepContext) -> Result<StepOutput> {
match ctx.config.cloudfront.as_ref() {
Some(cf) => Ok(StepOutput::ok(format!(
"Would invalidate {} on distribution {}",
cf.paths.join(", "),
cf.distribution_id
))),
None => Ok(StepOutput::skipped("No CloudFront configuration")),
}
}
}