1use std::sync::Arc;
2
3use awsim_core::{
4 AccountRegionStore, AwsError, CloudMapRegistrar, ParameterLookup, PrincipalLookup, Protocol,
5 RequestContext, SecretLookup, ServiceHandler,
6};
7use serde_json::Value;
8use tracing::debug;
9
10use crate::operations::{clusters, container_instances, extras, services, task_definitions, tasks};
11use crate::state::EcsState;
12
13pub struct EcsService {
15 store: AccountRegionStore<EcsState>,
16 iam_lookup: Option<Arc<dyn PrincipalLookup>>,
20 secrets_lookup: Option<Arc<dyn SecretLookup>>,
25 parameters_lookup: Option<Arc<dyn ParameterLookup>>,
29 cloudmap_registrar: Option<Arc<dyn CloudMapRegistrar>>,
32}
33
34impl EcsService {
35 pub fn new() -> Self {
36 Self {
37 store: AccountRegionStore::new(),
38 iam_lookup: None,
39 secrets_lookup: None,
40 parameters_lookup: None,
41 cloudmap_registrar: None,
42 }
43 }
44
45 pub fn with_iam_lookup(mut self, lookup: Arc<dyn PrincipalLookup>) -> Self {
48 self.iam_lookup = Some(lookup);
49 self
50 }
51
52 pub fn with_secrets_lookup(mut self, lookup: Arc<dyn SecretLookup>) -> Self {
56 self.secrets_lookup = Some(lookup);
57 self
58 }
59
60 pub fn with_parameters_lookup(mut self, lookup: Arc<dyn ParameterLookup>) -> Self {
64 self.parameters_lookup = Some(lookup);
65 self
66 }
67
68 pub fn with_cloudmap_registrar(mut self, registrar: Arc<dyn CloudMapRegistrar>) -> Self {
72 self.cloudmap_registrar = Some(registrar);
73 self
74 }
75}
76
77impl Default for EcsService {
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83#[async_trait::async_trait]
84impl ServiceHandler for EcsService {
85 fn service_name(&self) -> &str {
86 "ecs"
87 }
88
89 fn signing_name(&self) -> &str {
90 "ecs"
91 }
92
93 fn protocol(&self) -> Protocol {
94 Protocol::AwsJson1_1
95 }
96
97 async fn handle(
98 &self,
99 operation: &str,
100 input: Value,
101 ctx: &RequestContext,
102 ) -> Result<Value, AwsError> {
103 debug!(operation = %operation, "ECS operation");
104
105 let state = self.store.get(&ctx.account_id, &ctx.region);
106
107 match operation {
108 "CreateCluster" => clusters::create_cluster(&state, &input, ctx),
110 "DeleteCluster" => clusters::delete_cluster(&state, &input, ctx),
111 "DescribeClusters" => clusters::describe_clusters(&state, &input, ctx),
112 "ListClusters" => clusters::list_clusters(&state, &input, ctx),
113
114 "RegisterTaskDefinition" => task_definitions::register_task_definition(
116 &state,
117 &input,
118 ctx,
119 self.iam_lookup.as_deref(),
120 self.secrets_lookup.as_deref(),
121 ),
122 "DeregisterTaskDefinition" => {
123 task_definitions::deregister_task_definition(&state, &input, ctx)
124 }
125 "DescribeTaskDefinition" => {
126 task_definitions::describe_task_definition(&state, &input, ctx)
127 }
128 "ListTaskDefinitions" => task_definitions::list_task_definitions(&state, &input, ctx),
129 "ListTaskDefinitionFamilies" => {
130 task_definitions::list_task_definition_families(&state, &input, ctx)
131 }
132
133 "CreateService" => {
135 services::create_service(&state, &input, ctx, self.cloudmap_registrar.as_deref())
136 }
137 "DeleteService" => {
138 services::delete_service(&state, &input, ctx, self.cloudmap_registrar.as_deref())
139 }
140 "DescribeServices" => services::describe_services(&state, &input, ctx),
141 "ListServices" => services::list_services(&state, &input, ctx),
142 "UpdateService" => services::update_service(&state, &input, ctx),
143
144 "RunTask" => tasks::run_task(
146 &state,
147 &input,
148 ctx,
149 self.secrets_lookup.as_deref(),
150 self.parameters_lookup.as_deref(),
151 ),
152 "StopTask" => tasks::stop_task(&state, &input, ctx),
153 "DescribeTasks" => tasks::describe_tasks(&state, &input, ctx),
154 "ListTasks" => tasks::list_tasks(&state, &input, ctx),
155
156 "TagResource" => extras::tag_resource(&state, &input, ctx),
158 "UntagResource" => extras::untag_resource(&state, &input, ctx),
159 "ListTagsForResource" => extras::list_tags_for_resource(&state, &input, ctx),
160
161 "PutClusterCapacityProviders" => {
163 extras::put_cluster_capacity_providers(&state, &input, ctx)
164 }
165 "DescribeCapacityProviders" => extras::describe_capacity_providers(&state, &input, ctx),
166
167 "PutAccountSetting" => extras::put_account_setting(&state, &input, ctx),
169 "PutAccountSettingDefault" => extras::put_account_setting(&state, &input, ctx),
170 "ListAccountSettings" => extras::list_account_settings(&state, &input, ctx),
171
172 "DiscoverPollEndpoint" => extras::discover_poll_endpoint(&state, &input, ctx),
174 "UpdateContainerAgent" => extras::update_container_agent(&state, &input, ctx),
175
176 "DescribeContainerInstances" => {
178 container_instances::describe_container_instances(&state, &input, ctx)
179 }
180 "ListContainerInstances" => {
181 container_instances::list_container_instances(&state, &input, ctx)
182 }
183 "ListAttributes" => container_instances::list_attributes(&state, &input, ctx),
184 "PutAttributes" => container_instances::put_attributes(&state, &input, ctx),
185 "DeleteAttributes" => container_instances::delete_attributes(&state, &input, ctx),
186 "ListServicesByNamespace" => {
187 container_instances::list_services_by_namespace(&state, &input, ctx)
188 }
189
190 _ => Err(AwsError::unknown_operation(operation)),
191 }
192 }
193}