#![allow(clippy::too_many_arguments)]
use serde_json::{json, Value};
use fakecloud_core::service::{AwsRequest, AwsResponse, AwsServiceError};
use super::*;
const SETTING_NAME_VALUES: &[&str] = &[
"serviceLongArnFormat",
"taskLongArnFormat",
"containerInstanceLongArnFormat",
"awsvpcTrunking",
"containerInsights",
"fargateFIPSMode",
"tagResourceAuthorization",
"fargateTaskRetirementWaitPeriod",
"guardDutyActivate",
"defaultLogDriverMode",
"fargateEventWindows",
];
impl EcsService {
pub(super) fn put_account_setting(
&self,
request: &AwsRequest,
) -> Result<AwsResponse, AwsServiceError> {
let body = request.json_body();
validate_enum_opt(&body, "name", SETTING_NAME_VALUES)?;
let name = req_str(&body, "name")?.to_string();
let value = req_str(&body, "value")?.to_string();
let principal_arn = opt_str(&body, "principalArn")
.map(String::from)
.or_else(|| request.principal.as_ref().map(|p| p.arn.clone()))
.unwrap_or_else(|| Arn::global("iam", &request.account_id, "root").to_string());
let account = request.account_id.clone();
let mut accounts = self.state.write();
let state = accounts.get_or_create(&account);
state
.principal_account_settings
.entry(principal_arn.clone())
.or_default()
.insert(name.clone(), value.clone());
Ok(AwsResponse::ok_json(json!({
"setting": {
"name": name,
"value": value,
"principalArn": principal_arn,
}
})))
}
pub(super) fn put_account_setting_default(
&self,
request: &AwsRequest,
) -> Result<AwsResponse, AwsServiceError> {
let body = request.json_body();
validate_enum_opt(&body, "name", SETTING_NAME_VALUES)?;
let name = req_str(&body, "name")?.to_string();
let value = req_str(&body, "value")?.to_string();
let account = request.account_id.clone();
let mut accounts = self.state.write();
let state = accounts.get_or_create(&account);
state
.account_setting_defaults
.insert(name.clone(), value.clone());
Ok(AwsResponse::ok_json(json!({
"setting": {
"name": name,
"value": value,
"principalArn": Arn::global("iam", &state.account_id, "root").to_string(),
}
})))
}
pub(super) fn delete_account_setting(
&self,
request: &AwsRequest,
) -> Result<AwsResponse, AwsServiceError> {
let body = request.json_body();
validate_enum_opt(&body, "name", SETTING_NAME_VALUES)?;
let name = req_str(&body, "name")?.to_string();
let principal_arn = opt_str(&body, "principalArn")
.map(String::from)
.or_else(|| request.principal.as_ref().map(|p| p.arn.clone()))
.unwrap_or_else(|| Arn::global("iam", &request.account_id, "root").to_string());
let account = request.account_id.clone();
let mut accounts = self.state.write();
let state = accounts.get_or_create(&account);
let removed_value = state
.principal_account_settings
.get_mut(&principal_arn)
.and_then(|m| m.remove(&name));
Ok(AwsResponse::ok_json(json!({
"setting": {
"name": name,
"value": removed_value.unwrap_or_default(),
"principalArn": principal_arn,
}
})))
}
pub(super) fn list_account_settings(
&self,
request: &AwsRequest,
) -> Result<AwsResponse, AwsServiceError> {
let body = request.json_body();
validate_enum_opt(&body, "name", SETTING_NAME_VALUES)?;
let name_filter = opt_str(&body, "name");
let value_filter = opt_str(&body, "value");
let principal_filter = opt_str(&body, "principalArn");
let effective_only = body
.get("effectiveSettings")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let account = request.account_id.clone();
let accounts = self.state.read();
let Some(state) = accounts.get(&account) else {
return Ok(AwsResponse::ok_json(json!({"settings": []})));
};
let root_arn = Arn::global("iam", &state.account_id, "root").to_string();
let mut settings: Vec<Value> = Vec::new();
if effective_only {
let principal = principal_filter
.map(String::from)
.or_else(|| request.principal.as_ref().map(|p| p.arn.clone()))
.unwrap_or_else(|| root_arn.clone());
let mut merged = state.account_setting_defaults.clone();
if let Some(overrides) = state.principal_account_settings.get(&principal) {
for (k, v) in overrides {
merged.insert(k.clone(), v.clone());
}
}
for (k, v) in merged {
if matches_filter(name_filter, &k) && matches_filter(value_filter, &v) {
settings.push(json!({
"name": k,
"value": v,
"principalArn": principal,
}));
}
}
} else {
for (k, v) in &state.account_setting_defaults {
if matches_filter(name_filter, k)
&& matches_filter(value_filter, v)
&& (principal_filter.is_none() || principal_filter == Some(root_arn.as_str()))
{
settings.push(json!({
"name": k,
"value": v,
"principalArn": root_arn,
}));
}
}
for (principal, entries) in &state.principal_account_settings {
if principal_filter.is_some_and(|pf| pf != principal) {
continue;
}
for (k, v) in entries {
if matches_filter(name_filter, k) && matches_filter(value_filter, v) {
settings.push(json!({
"name": k,
"value": v,
"principalArn": principal,
}));
}
}
}
}
Ok(AwsResponse::ok_json(json!({"settings": settings})))
}
}