Skip to main content

awsim_cloudfront/
lib.rs

1mod ids;
2mod operations;
3mod state;
4
5use std::sync::Arc;
6
7use async_trait::async_trait;
8use awsim_core::{
9    AccountRegionStore, AwsError, Protocol, RequestContext, RouteDefinition, ServiceHandler,
10};
11use serde_json::Value;
12use tracing::debug;
13
14use state::CloudFrontState;
15
16/// The AWSim CloudFront service handler.
17pub struct CloudFrontService {
18    store: AccountRegionStore<CloudFrontState>,
19}
20
21impl CloudFrontService {
22    pub fn new() -> Self {
23        Self {
24            store: AccountRegionStore::new(),
25        }
26    }
27
28    /// CloudFront state is global per account — region is not used.
29    fn get_state(&self, ctx: &RequestContext) -> Arc<CloudFrontState> {
30        self.store.get(&ctx.account_id, "global")
31    }
32}
33
34impl Default for CloudFrontService {
35    fn default() -> Self {
36        Self::new()
37    }
38}
39
40#[async_trait]
41impl ServiceHandler for CloudFrontService {
42    fn service_name(&self) -> &str {
43        "cloudfront"
44    }
45
46    fn signing_name(&self) -> &str {
47        "cloudfront"
48    }
49
50    fn protocol(&self) -> Protocol {
51        Protocol::RestXml
52    }
53
54    fn routes(&self) -> Vec<RouteDefinition> {
55        vec![
56            // Distributions
57            RouteDefinition {
58                method: "POST",
59                path_pattern: "/2020-05-31/distribution",
60                operation: "CreateDistribution",
61                required_query_param: None,
62            },
63            RouteDefinition {
64                method: "GET",
65                path_pattern: "/2020-05-31/distribution",
66                operation: "ListDistributions",
67                required_query_param: None,
68            },
69            RouteDefinition {
70                method: "GET",
71                path_pattern: "/2020-05-31/distribution/{Id}",
72                operation: "GetDistribution",
73                required_query_param: None,
74            },
75            RouteDefinition {
76                method: "DELETE",
77                path_pattern: "/2020-05-31/distribution/{Id}",
78                operation: "DeleteDistribution",
79                required_query_param: None,
80            },
81            RouteDefinition {
82                method: "PUT",
83                path_pattern: "/2020-05-31/distribution/{Id}/config",
84                operation: "UpdateDistribution",
85                required_query_param: None,
86            },
87            RouteDefinition {
88                method: "GET",
89                path_pattern: "/2020-05-31/distribution/{Id}/config",
90                operation: "GetDistributionConfig",
91                required_query_param: None,
92            },
93            // Invalidations
94            RouteDefinition {
95                method: "POST",
96                path_pattern: "/2020-05-31/distribution/{DistributionId}/invalidation",
97                operation: "CreateInvalidation",
98                required_query_param: None,
99            },
100            RouteDefinition {
101                method: "GET",
102                path_pattern: "/2020-05-31/distribution/{DistributionId}/invalidation",
103                operation: "ListInvalidations",
104                required_query_param: None,
105            },
106            RouteDefinition {
107                method: "GET",
108                path_pattern: "/2020-05-31/distribution/{DistributionId}/invalidation/{Id}",
109                operation: "GetInvalidation",
110                required_query_param: None,
111            },
112            // Origin Access Controls
113            RouteDefinition {
114                method: "POST",
115                path_pattern: "/2020-05-31/origin-access-control",
116                operation: "CreateOriginAccessControl",
117                required_query_param: None,
118            },
119            RouteDefinition {
120                method: "GET",
121                path_pattern: "/2020-05-31/origin-access-control",
122                operation: "ListOriginAccessControls",
123                required_query_param: None,
124            },
125            RouteDefinition {
126                method: "DELETE",
127                path_pattern: "/2020-05-31/origin-access-control/{Id}",
128                operation: "DeleteOriginAccessControl",
129                required_query_param: None,
130            },
131            // Legacy OAIs
132            RouteDefinition {
133                method: "POST",
134                path_pattern: "/2020-05-31/origin-access-identity/cloudfront",
135                operation: "CreateCloudFrontOriginAccessIdentity",
136                required_query_param: None,
137            },
138            RouteDefinition {
139                method: "GET",
140                path_pattern: "/2020-05-31/origin-access-identity/cloudfront/{Id}",
141                operation: "GetCloudFrontOriginAccessIdentity",
142                required_query_param: None,
143            },
144            RouteDefinition {
145                method: "GET",
146                path_pattern: "/2020-05-31/origin-access-identity/cloudfront",
147                operation: "ListCloudFrontOriginAccessIdentities",
148                required_query_param: None,
149            },
150            // Cache Policies
151            RouteDefinition {
152                method: "POST",
153                path_pattern: "/2020-05-31/cache-policy",
154                operation: "CreateCachePolicy",
155                required_query_param: None,
156            },
157            RouteDefinition {
158                method: "GET",
159                path_pattern: "/2020-05-31/cache-policy",
160                operation: "ListCachePolicies",
161                required_query_param: None,
162            },
163            RouteDefinition {
164                method: "GET",
165                path_pattern: "/2020-05-31/cache-policy/{Id}",
166                operation: "GetCachePolicy",
167                required_query_param: None,
168            },
169            RouteDefinition {
170                method: "DELETE",
171                path_pattern: "/2020-05-31/cache-policy/{Id}",
172                operation: "DeleteCachePolicy",
173                required_query_param: None,
174            },
175            // Response Headers Policies
176            RouteDefinition {
177                method: "GET",
178                path_pattern: "/2020-05-31/response-headers-policy",
179                operation: "ListResponseHeadersPolicies",
180                required_query_param: None,
181            },
182            // Tags
183            RouteDefinition {
184                method: "POST",
185                path_pattern: "/2020-05-31/tagging",
186                operation: "TagResource",
187                required_query_param: Some("Operation=Tag"),
188            },
189            RouteDefinition {
190                method: "GET",
191                path_pattern: "/2020-05-31/tagging",
192                operation: "ListTagsForResource",
193                required_query_param: None,
194            },
195            // Origin Request Policies
196            RouteDefinition {
197                method: "POST",
198                path_pattern: "/2020-05-31/origin-request-policy",
199                operation: "CreateOriginRequestPolicy",
200                required_query_param: None,
201            },
202            RouteDefinition {
203                method: "GET",
204                path_pattern: "/2020-05-31/origin-request-policy",
205                operation: "ListOriginRequestPolicies",
206                required_query_param: None,
207            },
208            RouteDefinition {
209                method: "GET",
210                path_pattern: "/2020-05-31/origin-request-policy/{Id}",
211                operation: "GetOriginRequestPolicy",
212                required_query_param: None,
213            },
214            RouteDefinition {
215                method: "DELETE",
216                path_pattern: "/2020-05-31/origin-request-policy/{Id}",
217                operation: "DeleteOriginRequestPolicy",
218                required_query_param: None,
219            },
220            // Key Groups
221            RouteDefinition {
222                method: "POST",
223                path_pattern: "/2020-05-31/key-group",
224                operation: "CreateKeyGroup",
225                required_query_param: None,
226            },
227            RouteDefinition {
228                method: "GET",
229                path_pattern: "/2020-05-31/key-group",
230                operation: "ListKeyGroups",
231                required_query_param: None,
232            },
233            RouteDefinition {
234                method: "GET",
235                path_pattern: "/2020-05-31/key-group/{Id}",
236                operation: "GetKeyGroup",
237                required_query_param: None,
238            },
239            RouteDefinition {
240                method: "DELETE",
241                path_pattern: "/2020-05-31/key-group/{Id}",
242                operation: "DeleteKeyGroup",
243                required_query_param: None,
244            },
245            // Public Keys
246            RouteDefinition {
247                method: "POST",
248                path_pattern: "/2020-05-31/public-key",
249                operation: "CreatePublicKey",
250                required_query_param: None,
251            },
252            RouteDefinition {
253                method: "GET",
254                path_pattern: "/2020-05-31/public-key",
255                operation: "ListPublicKeys",
256                required_query_param: None,
257            },
258            RouteDefinition {
259                method: "GET",
260                path_pattern: "/2020-05-31/public-key/{Id}",
261                operation: "GetPublicKey",
262                required_query_param: None,
263            },
264            RouteDefinition {
265                method: "DELETE",
266                path_pattern: "/2020-05-31/public-key/{Id}",
267                operation: "DeletePublicKey",
268                required_query_param: None,
269            },
270            // Field Level Encryption
271            RouteDefinition {
272                method: "POST",
273                path_pattern: "/2020-05-31/field-level-encryption",
274                operation: "CreateFieldLevelEncryptionConfig",
275                required_query_param: None,
276            },
277            RouteDefinition {
278                method: "GET",
279                path_pattern: "/2020-05-31/field-level-encryption",
280                operation: "ListFieldLevelEncryptionConfigs",
281                required_query_param: None,
282            },
283            RouteDefinition {
284                method: "GET",
285                path_pattern: "/2020-05-31/field-level-encryption/{Id}",
286                operation: "GetFieldLevelEncryptionConfig",
287                required_query_param: None,
288            },
289            RouteDefinition {
290                method: "DELETE",
291                path_pattern: "/2020-05-31/field-level-encryption/{Id}",
292                operation: "DeleteFieldLevelEncryptionConfig",
293                required_query_param: None,
294            },
295            // Real-time Log Configs
296            RouteDefinition {
297                method: "POST",
298                path_pattern: "/2020-05-31/realtime-log-config",
299                operation: "CreateRealtimeLogConfig",
300                required_query_param: None,
301            },
302            RouteDefinition {
303                method: "GET",
304                path_pattern: "/2020-05-31/realtime-log-config",
305                operation: "ListRealtimeLogConfigs",
306                required_query_param: None,
307            },
308            RouteDefinition {
309                method: "PUT",
310                path_pattern: "/2020-05-31/realtime-log-config",
311                operation: "GetRealtimeLogConfig",
312                required_query_param: None,
313            },
314            RouteDefinition {
315                method: "DELETE",
316                path_pattern: "/2020-05-31/delete-realtime-log-config",
317                operation: "DeleteRealtimeLogConfig",
318                required_query_param: None,
319            },
320            // CloudFront Functions
321            RouteDefinition {
322                method: "POST",
323                path_pattern: "/2020-05-31/function",
324                operation: "CreateFunction",
325                required_query_param: None,
326            },
327            RouteDefinition {
328                method: "GET",
329                path_pattern: "/2020-05-31/function",
330                operation: "ListFunctions",
331                required_query_param: None,
332            },
333            RouteDefinition {
334                method: "GET",
335                path_pattern: "/2020-05-31/function/{Name}/describe",
336                operation: "DescribeFunction",
337                required_query_param: None,
338            },
339            RouteDefinition {
340                method: "DELETE",
341                path_pattern: "/2020-05-31/function/{Name}",
342                operation: "DeleteFunction",
343                required_query_param: None,
344            },
345            RouteDefinition {
346                method: "POST",
347                path_pattern: "/2020-05-31/function/{Name}/publish",
348                operation: "PublishFunction",
349                required_query_param: None,
350            },
351            // List by web ACL / realtime log config
352            RouteDefinition {
353                method: "GET",
354                path_pattern: "/2020-05-31/distributionsByWebACLId/{WebACLId}",
355                operation: "ListDistributionsByWebACLId",
356                required_query_param: None,
357            },
358            RouteDefinition {
359                method: "POST",
360                path_pattern: "/2020-05-31/distributionsByRealtimeLogConfig",
361                operation: "ListDistributionsByRealtimeLogConfig",
362                required_query_param: None,
363            },
364        ]
365    }
366
367    async fn handle(
368        &self,
369        operation: &str,
370        input: Value,
371        ctx: &RequestContext,
372    ) -> Result<Value, AwsError> {
373        debug!(operation, "CloudFront request");
374        let state = self.get_state(ctx);
375
376        match operation {
377            // Distributions
378            "CreateDistribution" => {
379                operations::distributions::create_distribution(&state, &input, ctx)
380            }
381            "GetDistribution" => {
382                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
383                operations::distributions::get_distribution(&state, id)
384            }
385            "GetDistributionConfig" => {
386                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
387                operations::distributions::get_distribution_config(&state, id)
388            }
389            "ListDistributions" => operations::distributions::list_distributions(&state),
390            "DeleteDistribution" => {
391                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
392                operations::distributions::delete_distribution(&state, id)
393            }
394            "UpdateDistribution" => {
395                let id = input
396                    .get("Id")
397                    .and_then(|v| v.as_str())
398                    .unwrap_or("")
399                    .to_string();
400                operations::distributions::update_distribution(&state, &id, &input)
401            }
402
403            // Invalidations
404            "CreateInvalidation" => {
405                let dist_id = input
406                    .get("DistributionId")
407                    .and_then(|v| v.as_str())
408                    .unwrap_or("");
409                operations::invalidations::create_invalidation(&state, dist_id, &input)
410            }
411            "GetInvalidation" => {
412                let dist_id = input
413                    .get("DistributionId")
414                    .and_then(|v| v.as_str())
415                    .unwrap_or("");
416                let inv_id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
417                operations::invalidations::get_invalidation(&state, dist_id, inv_id)
418            }
419            "ListInvalidations" => {
420                let dist_id = input
421                    .get("DistributionId")
422                    .and_then(|v| v.as_str())
423                    .unwrap_or("");
424                operations::invalidations::list_invalidations(&state, dist_id)
425            }
426
427            // Origin Access Controls
428            "CreateOriginAccessControl" => {
429                operations::origin_access::create_origin_access_control(&state, &input)
430            }
431            "ListOriginAccessControls" => {
432                operations::origin_access::list_origin_access_controls(&state)
433            }
434            "DeleteOriginAccessControl" => {
435                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
436                operations::origin_access::delete_origin_access_control(&state, id)
437            }
438
439            // Legacy OAIs
440            "CreateCloudFrontOriginAccessIdentity" => operations::oai::create_oai(&state, &input),
441            "GetCloudFrontOriginAccessIdentity" => {
442                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
443                operations::oai::get_oai(&state, id)
444            }
445            "ListCloudFrontOriginAccessIdentities" => operations::oai::list_oais(&state),
446
447            // Cache Policies
448            "CreateCachePolicy" => operations::cache_policies::create_cache_policy(&state, &input),
449            "GetCachePolicy" => {
450                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
451                operations::cache_policies::get_cache_policy(&state, id)
452            }
453            "DeleteCachePolicy" => {
454                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
455                operations::cache_policies::delete_cache_policy(&state, id)
456            }
457            "ListCachePolicies" => operations::cache_policies::list_cache_policies(&state),
458
459            // Response Headers Policies
460            "ListResponseHeadersPolicies" => {
461                operations::response_headers_policies::list_response_headers_policies(&state)
462            }
463
464            // Tags
465            "TagResource" => operations::tags::tag_resource(&state, &input),
466            "ListTagsForResource" => operations::tags::list_tags_for_resource(&state, &input),
467
468            // Origin Request Policies
469            "CreateOriginRequestPolicy" => {
470                operations::origin_request_policies::create_origin_request_policy(&state, &input)
471            }
472            "GetOriginRequestPolicy" => {
473                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
474                operations::origin_request_policies::get_origin_request_policy(&state, id)
475            }
476            "DeleteOriginRequestPolicy" => {
477                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
478                operations::origin_request_policies::delete_origin_request_policy(&state, id)
479            }
480            "ListOriginRequestPolicies" => {
481                operations::origin_request_policies::list_origin_request_policies(&state)
482            }
483
484            // Key Groups
485            "CreateKeyGroup" => operations::key_groups::create_key_group(&state, &input),
486            "GetKeyGroup" => {
487                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
488                operations::key_groups::get_key_group(&state, id)
489            }
490            "DeleteKeyGroup" => {
491                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
492                operations::key_groups::delete_key_group(&state, id)
493            }
494            "ListKeyGroups" => operations::key_groups::list_key_groups(&state),
495
496            // Public Keys
497            "CreatePublicKey" => operations::public_keys::create_public_key(&state, &input),
498            "GetPublicKey" => {
499                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
500                operations::public_keys::get_public_key(&state, id)
501            }
502            "DeletePublicKey" => {
503                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
504                operations::public_keys::delete_public_key(&state, id)
505            }
506            "ListPublicKeys" => operations::public_keys::list_public_keys(&state),
507
508            // Field Level Encryption
509            "CreateFieldLevelEncryptionConfig" => {
510                operations::field_level_encryption::create_field_level_encryption_config(
511                    &state, &input,
512                )
513            }
514            "GetFieldLevelEncryptionConfig" => {
515                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
516                operations::field_level_encryption::get_field_level_encryption_config(&state, id)
517            }
518            "DeleteFieldLevelEncryptionConfig" => {
519                let id = input.get("Id").and_then(|v| v.as_str()).unwrap_or("");
520                operations::field_level_encryption::delete_field_level_encryption_config(&state, id)
521            }
522            "ListFieldLevelEncryptionConfigs" => {
523                operations::field_level_encryption::list_field_level_encryption_configs(&state)
524            }
525
526            // Real-time Log Configs
527            "CreateRealtimeLogConfig" => {
528                operations::realtime_logs::create_realtime_log_config(&state, &input)
529            }
530            "GetRealtimeLogConfig" => {
531                operations::realtime_logs::get_realtime_log_config(&state, &input)
532            }
533            "DeleteRealtimeLogConfig" => {
534                operations::realtime_logs::delete_realtime_log_config(&state, &input)
535            }
536            "ListRealtimeLogConfigs" => {
537                operations::realtime_logs::list_realtime_log_configs(&state)
538            }
539
540            // CloudFront Functions
541            "CreateFunction" => operations::functions::create_function(&state, &input),
542            "DescribeFunction" => {
543                let name = input.get("Name").and_then(|v| v.as_str()).unwrap_or("");
544                operations::functions::describe_function(&state, name)
545            }
546            "DeleteFunction" => {
547                let name = input.get("Name").and_then(|v| v.as_str()).unwrap_or("");
548                operations::functions::delete_function(&state, name)
549            }
550            "ListFunctions" => operations::functions::list_functions(&state),
551            "PublishFunction" => {
552                let name = input.get("Name").and_then(|v| v.as_str()).unwrap_or("");
553                operations::functions::publish_function(&state, name)
554            }
555
556            // Distribution listings
557            "ListDistributionsByWebACLId" => {
558                let acl = input.get("WebACLId").and_then(|v| v.as_str()).unwrap_or("");
559                operations::extras::list_distributions_by_web_acl_id(&state, acl)
560            }
561            "ListDistributionsByRealtimeLogConfig" => {
562                operations::extras::list_distributions_by_realtime_log_config(&state, &input)
563            }
564
565            _ => Err(AwsError::unknown_operation(operation)),
566        }
567    }
568}