refactor: simplify crud-pricing to pure CRUD layer - remove AWS API clients
All checks were successful
kinec.tech/airun-pathfinder-crud-pricing/pipeline/head This commit looks good
All checks were successful
kinec.tech/airun-pathfinder-crud-pricing/pipeline/head This commit looks good
Removed AWS Pricing API and Cost Explorer clients to make crud-pricing a pure DynamoDB CRUD layer. This fixes layer violation where CRUD was making external AWS API calls. Changes: - Deleted src/aws_pricing.rs (AWS Pricing API client) - Deleted src/cost_explorer.rs (Cost Explorer client) - Removed PricingClient and StsClient from main.rs - Removed QueryAwsApi and QueryCostExplorer operations - Removed fetch_if_missing behavior (Get operation now only reads from cache) - Removed aws-sdk-pricing, aws-sdk-costexplorer, aws-sdk-sts dependencies - Removed pricing_api_access and sts_assume_role IAM policies Result: Pure CRUD layer with only DynamoDB operations (Get, Put, ListCommon, IncrementAccess) Reduced from ~1100 lines to ~600 lines 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
112
src/main.rs
112
src/main.rs
@@ -1,12 +1,8 @@
|
||||
mod aws_pricing;
|
||||
mod cost_explorer;
|
||||
mod db;
|
||||
mod models;
|
||||
|
||||
use aws_config::BehaviorVersion;
|
||||
use aws_sdk_dynamodb::Client as DynamoDbClient;
|
||||
use aws_sdk_pricing::Client as PricingClient;
|
||||
use aws_sdk_sts::Client as StsClient;
|
||||
use lambda_runtime::{service_fn, Error, LambdaEvent};
|
||||
use serde_json::Value;
|
||||
use std::env;
|
||||
@@ -44,8 +40,6 @@ async fn function_handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
|
||||
// Load AWS config and create clients
|
||||
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;
|
||||
let dynamodb_client = DynamoDbClient::new(&config);
|
||||
let pricing_client = PricingClient::new(&config);
|
||||
let sts_client = StsClient::new(&config);
|
||||
|
||||
let table_name = env::var("TABLE_NAME").unwrap_or_else(|_| "pathfinder-dev-pricing".to_string());
|
||||
|
||||
@@ -53,8 +47,6 @@ async fn function_handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
|
||||
let result = handle_operation(
|
||||
request.operation,
|
||||
&dynamodb_client,
|
||||
&pricing_client,
|
||||
&sts_client,
|
||||
&table_name,
|
||||
)
|
||||
.await;
|
||||
@@ -73,8 +65,6 @@ async fn function_handler(event: LambdaEvent<Value>) -> Result<Value, Error> {
|
||||
async fn handle_operation(
|
||||
operation: PricingOperation,
|
||||
dynamodb_client: &DynamoDbClient,
|
||||
pricing_client: &PricingClient,
|
||||
sts_client: &StsClient,
|
||||
table_name: &str,
|
||||
) -> Result<Value, String> {
|
||||
match operation {
|
||||
@@ -83,9 +73,9 @@ async fn handle_operation(
|
||||
region,
|
||||
pricing_type,
|
||||
aws_account_id,
|
||||
fetch_if_missing,
|
||||
fetch_if_missing: _,
|
||||
} => {
|
||||
info!("Operation: Get (type={:?}, fetch_if_missing={})", pricing_type, fetch_if_missing);
|
||||
info!("Operation: Get (type={:?})", pricing_type);
|
||||
|
||||
// Check cache
|
||||
let cached = db::get_pricing(
|
||||
@@ -126,30 +116,8 @@ async fn handle_operation(
|
||||
"cacheStatus": "hit"
|
||||
}))
|
||||
}
|
||||
None if fetch_if_missing => {
|
||||
// Cache miss - fetch from AWS
|
||||
info!("Cache miss, fetching from AWS API");
|
||||
|
||||
let pricing = fetch_pricing(
|
||||
pricing_client,
|
||||
sts_client,
|
||||
&instance_type,
|
||||
®ion,
|
||||
&pricing_type,
|
||||
aws_account_id.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Cache it
|
||||
db::put_pricing(dynamodb_client, table_name, &pricing).await?;
|
||||
|
||||
Ok(serde_json::json!({
|
||||
"pricing": pricing,
|
||||
"cacheStatus": "miss"
|
||||
}))
|
||||
}
|
||||
None => {
|
||||
Err("Pricing not found and fetch_if_missing=false".to_string())
|
||||
Err("Pricing not found in cache".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,79 +177,5 @@ async fn handle_operation(
|
||||
"region": region
|
||||
}))
|
||||
}
|
||||
|
||||
PricingOperation::QueryAwsApi {
|
||||
instance_type,
|
||||
region,
|
||||
} => {
|
||||
info!("Operation: QueryAwsApi ({} in {})", instance_type, region);
|
||||
|
||||
let pricing = aws_pricing::fetch_ec2_pricing(pricing_client, &instance_type, ®ion).await?;
|
||||
|
||||
Ok(serde_json::json!({
|
||||
"pricing": pricing,
|
||||
"source": "aws-pricing-api"
|
||||
}))
|
||||
}
|
||||
|
||||
PricingOperation::QueryCostExplorer {
|
||||
instance_type,
|
||||
region,
|
||||
aws_account_id,
|
||||
role_arn,
|
||||
} => {
|
||||
info!(
|
||||
"Operation: QueryCostExplorer ({} in {}, account={})",
|
||||
instance_type, region, aws_account_id
|
||||
);
|
||||
|
||||
let pricing = cost_explorer::fetch_account_specific_pricing(
|
||||
sts_client,
|
||||
&instance_type,
|
||||
®ion,
|
||||
&aws_account_id,
|
||||
&role_arn,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(serde_json::json!({
|
||||
"pricing": pricing,
|
||||
"source": "cost-explorer",
|
||||
"includesEDP": true
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch pricing based on type (retail or account-specific)
|
||||
async fn fetch_pricing(
|
||||
pricing_client: &PricingClient,
|
||||
sts_client: &StsClient,
|
||||
instance_type: &str,
|
||||
region: &str,
|
||||
pricing_type: &PricingType,
|
||||
aws_account_id: Option<&str>,
|
||||
) -> Result<crate::models::PricingData, String> {
|
||||
match pricing_type {
|
||||
PricingType::Retail => {
|
||||
info!("Fetching retail pricing from AWS Pricing API");
|
||||
aws_pricing::fetch_ec2_pricing(pricing_client, instance_type, region).await
|
||||
}
|
||||
PricingType::AccountSpecific => {
|
||||
let account_id = aws_account_id.ok_or("aws_account_id required for account-specific pricing")?;
|
||||
|
||||
// Role ARN is expected to be in format: arn:aws:iam::{account_id}:role/pathfinder-pricing-access
|
||||
let role_arn = format!("arn:aws:iam::{}:role/pathfinder-pricing-access", account_id);
|
||||
|
||||
info!("Fetching account-specific pricing from Cost Explorer");
|
||||
cost_explorer::fetch_account_specific_pricing(
|
||||
sts_client,
|
||||
instance_type,
|
||||
region,
|
||||
account_id,
|
||||
&role_arn,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user