Skip to main content

fakecloud_sdk/
types.rs

1use serde::{Deserialize, Serialize};
2
3// ── Health ──────────────────────────────────────────────────────────
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(rename_all = "camelCase")]
7pub struct HealthResponse {
8    pub status: String,
9    pub version: String,
10    pub services: Vec<String>,
11}
12
13// ── Reset ───────────────────────────────────────────────────────────
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16#[serde(rename_all = "camelCase")]
17pub struct ResetResponse {
18    pub status: String,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22#[serde(rename_all = "camelCase")]
23pub struct ResetServiceResponse {
24    pub reset: String,
25}
26
27// ── RDS ─────────────────────────────────────────────────────────────
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(rename_all = "camelCase")]
31pub struct RdsTag {
32    pub key: String,
33    pub value: String,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37#[serde(rename_all = "camelCase")]
38pub struct RdsInstance {
39    pub db_instance_identifier: String,
40    pub db_instance_arn: String,
41    pub db_instance_class: String,
42    pub engine: String,
43    pub engine_version: String,
44    pub db_instance_status: String,
45    pub master_username: String,
46    pub db_name: Option<String>,
47    pub endpoint_address: String,
48    pub port: i32,
49    pub allocated_storage: i32,
50    pub publicly_accessible: bool,
51    pub deletion_protection: bool,
52    pub created_at: String,
53    pub dbi_resource_id: String,
54    pub container_id: String,
55    pub host_port: u16,
56    pub tags: Vec<RdsTag>,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(rename_all = "camelCase")]
61pub struct RdsInstancesResponse {
62    pub instances: Vec<RdsInstance>,
63}
64
65// ── Lambda ──────────────────────────────────────────────────────────
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
68#[serde(rename_all = "camelCase")]
69pub struct LambdaInvocation {
70    pub function_arn: String,
71    pub payload: String,
72    pub source: String,
73    pub timestamp: String,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct LambdaInvocationsResponse {
79    pub invocations: Vec<LambdaInvocation>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
83#[serde(rename_all = "camelCase")]
84pub struct WarmContainer {
85    pub function_name: String,
86    pub runtime: String,
87    pub container_id: String,
88    pub last_used_secs_ago: u64,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
92#[serde(rename_all = "camelCase")]
93pub struct WarmContainersResponse {
94    pub containers: Vec<WarmContainer>,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
98#[serde(rename_all = "camelCase")]
99pub struct EvictContainerResponse {
100    pub evicted: bool,
101}
102
103// ── SES ─────────────────────────────────────────────────────────────
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
106#[serde(rename_all = "camelCase")]
107pub struct SentEmail {
108    pub message_id: String,
109    pub from: String,
110    pub to: Vec<String>,
111    #[serde(default)]
112    pub cc: Vec<String>,
113    #[serde(default)]
114    pub bcc: Vec<String>,
115    pub subject: Option<String>,
116    pub html_body: Option<String>,
117    pub text_body: Option<String>,
118    pub raw_data: Option<String>,
119    pub template_name: Option<String>,
120    pub template_data: Option<String>,
121    #[serde(default)]
122    pub dkim_signature: Option<String>,
123    /// Synthesized RFC 5322 headers stamped onto the message at send
124    /// time. When DKIM is on, the first entry is `DKIM-Signature`. Each
125    /// pair is `(name, value)`.
126    #[serde(default)]
127    pub headers: Vec<(String, String)>,
128    pub timestamp: String,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
132#[serde(rename_all = "camelCase")]
133pub struct SesEmailsResponse {
134    pub emails: Vec<SentEmail>,
135}
136
137/// Admin payload to flip an identity's `MailFromDomainStatus` for tests.
138#[derive(Debug, Clone, Serialize, Deserialize)]
139#[serde(rename_all = "camelCase")]
140pub struct SesMailFromStatusRequest {
141    pub status: String,
142}
143
144// ── SES introspection: bounces / insights / SMTP submissions / event-dest ──
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147#[serde(rename_all = "camelCase")]
148pub struct SesBouncedRecipientInfo {
149    pub recipient: String,
150    pub bounce_type: String,
151    pub action: String,
152    pub status: String,
153    pub diagnostic_code: String,
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
157#[serde(rename_all = "camelCase")]
158pub struct SesBounce {
159    pub message_id: String,
160    pub bounce_type: String,
161    pub bounce_sub_type: String,
162    pub bounced_recipient_info: Vec<SesBouncedRecipientInfo>,
163    pub explanation: Option<String>,
164    pub timestamp: String,
165    pub original_message_id: String,
166    pub bounce_sender: String,
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize)]
170#[serde(rename_all = "camelCase")]
171pub struct SesBouncesResponse {
172    pub bounces: Vec<SesBounce>,
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
176#[serde(rename_all = "camelCase")]
177pub struct SesMessageInsightEvent {
178    pub destination: String,
179    pub timestamp: String,
180    #[serde(default, skip_serializing_if = "Option::is_none")]
181    pub bounce_type: Option<String>,
182    #[serde(default, skip_serializing_if = "Option::is_none")]
183    pub bounce_sub_type: Option<String>,
184    #[serde(default, skip_serializing_if = "Option::is_none")]
185    pub diagnostic_code: Option<String>,
186    #[serde(default, skip_serializing_if = "Option::is_none")]
187    pub complaint_feedback_type: Option<String>,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize)]
191#[serde(rename_all = "camelCase")]
192pub struct SesMessageInsightsResponse {
193    pub message_id: String,
194    pub sends: Vec<SesMessageInsightEvent>,
195    pub deliveries: Vec<SesMessageInsightEvent>,
196    pub opens: Vec<SesMessageInsightEvent>,
197    pub clicks: Vec<SesMessageInsightEvent>,
198    pub bounces: Vec<SesMessageInsightEvent>,
199    pub complaints: Vec<SesMessageInsightEvent>,
200    pub rejects: Vec<SesMessageInsightEvent>,
201}
202
203#[derive(Debug, Clone, Serialize, Deserialize)]
204#[serde(rename_all = "camelCase")]
205pub struct SesSmtpSubmission {
206    pub message_id: String,
207    pub from: String,
208    pub to: Vec<String>,
209    pub subject: Option<String>,
210    pub raw_size_bytes: usize,
211    pub received_at: String,
212    pub auth_user: String,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
216#[serde(rename_all = "camelCase")]
217pub struct SesSmtpSubmissionsResponse {
218    pub submissions: Vec<SesSmtpSubmission>,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
222#[serde(rename_all = "camelCase")]
223pub struct SesEventDestinationDelivery {
224    pub destination_name: String,
225    pub destination_type: String,
226    pub event_type: String,
227    pub message_id: String,
228    pub dispatched_at: String,
229    pub target_arn: String,
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
233#[serde(rename_all = "camelCase")]
234pub struct SesEventDestinationDeliveriesResponse {
235    pub deliveries: Vec<SesEventDestinationDelivery>,
236}
237
238/// Admin payload to flip the SES account-level `production_access_enabled`
239/// flag. fakecloud defaults to `production_access_enabled=true` so users
240/// don't have to verify recipients to send mail; flip this to `false` to
241/// exercise sandbox-mode semantics (verified-recipient gate, send quotas,
242/// etc.).
243#[derive(Debug, Clone, Serialize, Deserialize)]
244#[serde(rename_all = "camelCase")]
245pub struct SesSandboxRequest {
246    /// `true` puts the account back into sandbox mode (production access
247    /// disabled); `false` re-enables production access.
248    pub sandbox: bool,
249}
250
251/// Admin payload for `/_fakecloud/logs/anomalies/inject`. Lets tests
252/// seed synthetic CloudWatch Logs anomalies so they can exercise
253/// `ListAnomalies` / `UpdateAnomaly` deterministically.
254#[derive(Debug, Clone, Serialize, Deserialize)]
255#[serde(rename_all = "camelCase")]
256pub struct LogsAnomalyInjectRequest {
257    pub anomaly_detector_arn: String,
258    #[serde(default)]
259    pub log_group_arns: Vec<String>,
260    pub pattern_string: String,
261    #[serde(default)]
262    pub priority: Option<String>,
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize)]
266#[serde(rename_all = "camelCase")]
267pub struct LogsAnomalyInjectResponse {
268    pub anomaly_id: String,
269}
270
271/// One entry in the `/_fakecloud/logs/delivery-config` introspection
272/// response. Combines a `Delivery` with the `log_type` from its
273/// associated `DeliverySource` so test code can assert end-to-end
274/// configuration without joining state manually.
275#[derive(Debug, Clone, Serialize, Deserialize)]
276#[serde(rename_all = "camelCase")]
277pub struct LogsDeliveryConfiguration {
278    pub id: String,
279    /// Delivery identifier (same value as `id`; mirrors AWS naming).
280    pub name: String,
281    pub delivery_destination_arn: String,
282    pub delivery_source_name: String,
283    /// Log type from the associated `DeliverySource` (e.g. `ACCESS_LOGS`).
284    /// Empty string when the source has been deleted out from under the
285    /// delivery.
286    pub log_type: String,
287    #[serde(default)]
288    pub record_fields: Vec<String>,
289    #[serde(default)]
290    pub field_delimiter: Option<String>,
291    #[serde(default)]
292    pub s3_delivery_configuration: Option<serde_json::Value>,
293    /// Unix-ms timestamp of `CreateDelivery`. `0` for deliveries
294    /// recovered from older snapshots without this field.
295    pub created_at: i64,
296}
297
298#[derive(Debug, Clone, Serialize, Deserialize)]
299#[serde(rename_all = "camelCase")]
300pub struct LogsDeliveryConfigResponse {
301    pub configurations: Vec<LogsDeliveryConfiguration>,
302}
303
304/// One `Fields` entry parsed from a log group's index policy document.
305#[derive(Debug, Clone, Serialize, Deserialize)]
306#[serde(rename_all = "camelCase")]
307pub struct LogsFieldIndex {
308    /// Fields list from `IndexPolicy.policy_document.Fields`.
309    pub fields: Vec<String>,
310    /// Unix-ms when the policy was created. Mirrors `last_updated_time`
311    /// since fakecloud doesn't track a separate creation timestamp.
312    pub created_at: i64,
313    /// Unix-ms when the policy was last touched
314    /// (PutIndexPolicy updates).
315    pub last_used_at: i64,
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize)]
319#[serde(rename_all = "camelCase")]
320pub struct LogsFieldIndexesResponse {
321    pub log_group_name: String,
322    pub indexes: Vec<LogsFieldIndex>,
323}
324
325/// Admin payload for `/_fakecloud/cognito/compromised-passwords`.
326/// Plaintext passwords are hashed (sha256) and added to the
327/// compromised-credentials set consulted by `InitiateAuth` /
328/// `AdminInitiateAuth` when the pool's
329/// `CompromisedCredentialsRiskConfiguration.Actions.EventAction` is
330/// `BLOCK`.
331#[derive(Debug, Clone, Serialize, Deserialize)]
332#[serde(rename_all = "camelCase")]
333pub struct CognitoCompromisedPasswordsRequest {
334    pub passwords: Vec<String>,
335}
336
337#[derive(Debug, Clone, Serialize, Deserialize)]
338#[serde(rename_all = "camelCase")]
339pub struct InboundEmailRequest {
340    pub from: String,
341    pub to: Vec<String>,
342    pub subject: String,
343    pub body: String,
344}
345
346#[derive(Debug, Clone, Serialize, Deserialize)]
347#[serde(rename_all = "camelCase")]
348pub struct InboundActionExecuted {
349    pub rule: String,
350    pub action_type: String,
351}
352
353#[derive(Debug, Clone, Serialize, Deserialize)]
354#[serde(rename_all = "camelCase")]
355pub struct InboundEmailResponse {
356    pub message_id: String,
357    pub matched_rules: Vec<String>,
358    pub actions_executed: Vec<InboundActionExecuted>,
359}
360
361// ── SNS ─────────────────────────────────────────────────────────────
362
363#[derive(Debug, Clone, Serialize, Deserialize)]
364#[serde(rename_all = "camelCase")]
365pub struct SnsMessage {
366    pub message_id: String,
367    pub topic_arn: String,
368    pub message: String,
369    pub subject: Option<String>,
370    pub timestamp: String,
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize)]
374#[serde(rename_all = "camelCase")]
375pub struct SnsMessagesResponse {
376    pub messages: Vec<SnsMessage>,
377}
378
379#[derive(Debug, Clone, Serialize, Deserialize)]
380#[serde(rename_all = "camelCase")]
381pub struct SnsSmsMessage {
382    pub phone_number: String,
383    pub message: String,
384}
385
386#[derive(Debug, Clone, Serialize, Deserialize)]
387#[serde(rename_all = "camelCase")]
388pub struct SnsSmsResponse {
389    pub messages: Vec<SnsSmsMessage>,
390}
391
392#[derive(Debug, Clone, Serialize, Deserialize)]
393#[serde(rename_all = "camelCase")]
394pub struct PendingConfirmation {
395    pub subscription_arn: String,
396    pub topic_arn: String,
397    pub protocol: String,
398    pub endpoint: String,
399    pub token: Option<String>,
400}
401
402#[derive(Debug, Clone, Serialize, Deserialize)]
403#[serde(rename_all = "camelCase")]
404pub struct PendingConfirmationsResponse {
405    pub pending_confirmations: Vec<PendingConfirmation>,
406}
407
408#[derive(Debug, Clone, Serialize, Deserialize)]
409#[serde(rename_all = "camelCase")]
410pub struct ConfirmSubscriptionRequest {
411    pub subscription_arn: String,
412}
413
414#[derive(Debug, Clone, Serialize, Deserialize)]
415#[serde(rename_all = "camelCase")]
416pub struct ConfirmSubscriptionResponse {
417    pub confirmed: bool,
418}
419
420// ── SQS ─────────────────────────────────────────────────────────────
421
422#[derive(Debug, Clone, Serialize, Deserialize)]
423#[serde(rename_all = "camelCase")]
424pub struct SqsMessageInfo {
425    pub message_id: String,
426    pub body: String,
427    pub receive_count: u64,
428    pub in_flight: bool,
429    pub created_at: String,
430}
431
432#[derive(Debug, Clone, Serialize, Deserialize)]
433#[serde(rename_all = "camelCase")]
434pub struct SqsQueueMessages {
435    pub queue_url: String,
436    pub queue_name: String,
437    pub messages: Vec<SqsMessageInfo>,
438}
439
440#[derive(Debug, Clone, Serialize, Deserialize)]
441#[serde(rename_all = "camelCase")]
442pub struct SqsMessagesResponse {
443    pub queues: Vec<SqsQueueMessages>,
444}
445
446#[derive(Debug, Clone, Serialize, Deserialize)]
447#[serde(rename_all = "camelCase")]
448pub struct ExpirationTickResponse {
449    pub expired_messages: u64,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
453#[serde(rename_all = "camelCase")]
454pub struct ForceDlqResponse {
455    pub moved_messages: u64,
456}
457
458#[derive(Debug, Clone, Serialize, Deserialize)]
459#[serde(rename_all = "camelCase")]
460pub struct AppAsTickResponse {
461    /// Number of scaling decisions that were applied this tick.
462    pub applied: usize,
463}
464
465#[derive(Debug, Clone, Serialize, Deserialize)]
466#[serde(rename_all = "camelCase")]
467pub struct AppAsScheduledTickResponse {
468    /// Number of scheduled actions that fired this tick.
469    pub fired: usize,
470}
471
472#[derive(Debug, Clone, Serialize, Deserialize)]
473#[serde(rename_all = "camelCase")]
474pub struct SetSsmCommandStatusRequest {
475    pub account_id: Option<String>,
476    pub status: String,
477}
478
479#[derive(Debug, Clone, Serialize, Deserialize)]
480#[serde(rename_all = "camelCase")]
481pub struct SetSsmCommandStatusResponse {
482    pub updated: bool,
483}
484
485#[derive(Debug, Clone, Default, Serialize, Deserialize)]
486#[serde(rename_all = "camelCase")]
487pub struct FailSsmCommandRequest {
488    pub account_id: Option<String>,
489    /// Optional: target a single invocation. When `None`, every
490    /// invocation on the command is flipped to `Failed`.
491    pub instance_id: Option<String>,
492    /// Optional friendly status detail (e.g. "Script exited with code 7").
493    /// Defaults to "Failed".
494    pub status_details: Option<String>,
495    /// Optional captured stderr to expose via `GetCommandInvocation`.
496    pub standard_error_content: Option<String>,
497}
498
499#[derive(Debug, Clone, Serialize, Deserialize)]
500#[serde(rename_all = "camelCase")]
501pub struct FailSsmCommandResponse {
502    pub updated_invocations: usize,
503}
504
505/// One emitted parameter-policy event, as recorded by the
506/// `/_fakecloud/ssm/parameter-policy-events` admin endpoint.
507#[derive(Debug, Clone, Serialize, Deserialize)]
508#[serde(rename_all = "camelCase")]
509pub struct SsmParameterPolicyEvent {
510    pub parameter_name: String,
511    pub parameter_arn: String,
512    /// One of `ExpirationRegistered`, `ExpirationNotificationRegistered`,
513    /// `NoChangeNotificationRegistered`, `Expiration`,
514    /// `ExpirationNotification`, `NoChangeNotification`.
515    pub event_type: String,
516    pub message: String,
517    pub created_at: String,
518}
519
520#[derive(Debug, Clone, Serialize, Deserialize)]
521#[serde(rename_all = "camelCase")]
522pub struct SsmParameterPolicyEventsResponse {
523    pub events: Vec<SsmParameterPolicyEvent>,
524}
525
526/// Body shape for `POST /_fakecloud/ssm/sessions/inject`. Drops a fake
527/// session record into state without going through StartSession (which
528/// returns 501 unless `FAKECLOUD_SSM_SESSION_ECHO=1`). Lets tests assert
529/// `DescribeSessions`/`TerminateSession` paths work end-to-end.
530#[derive(Debug, Clone, Default, Serialize, Deserialize)]
531#[serde(rename_all = "camelCase")]
532pub struct InjectSsmSessionRequest {
533    pub account_id: Option<String>,
534    pub target: String,
535    /// Defaults to `Connected`; pass `Terminated` to seed a finished
536    /// session.
537    pub status: Option<String>,
538    /// Defaults to the account-root IAM ARN.
539    pub owner: Option<String>,
540    pub reason: Option<String>,
541    /// Optional explicit session ID. Falls back to the autogenerated
542    /// `session-XXXXXXXXXXXX` form when omitted or empty.
543    pub session_id: Option<String>,
544}
545
546#[derive(Debug, Clone, Serialize, Deserialize)]
547#[serde(rename_all = "camelCase")]
548pub struct InjectSsmSessionResponse {
549    pub session_id: String,
550}
551
552// ── EventBridge ─────────────────────────────────────────────────────
553
554#[derive(Debug, Clone, Serialize, Deserialize)]
555#[serde(rename_all = "camelCase")]
556pub struct EventBridgeEvent {
557    pub event_id: String,
558    pub source: String,
559    pub detail_type: String,
560    pub detail: String,
561    pub bus_name: String,
562    pub timestamp: String,
563}
564
565#[derive(Debug, Clone, Serialize, Deserialize)]
566#[serde(rename_all = "camelCase")]
567pub struct EventBridgeLambdaDelivery {
568    pub function_arn: String,
569    pub payload: String,
570    pub timestamp: String,
571}
572
573#[derive(Debug, Clone, Serialize, Deserialize)]
574#[serde(rename_all = "camelCase")]
575pub struct EventBridgeLogDelivery {
576    pub log_group_arn: String,
577    pub payload: String,
578    pub timestamp: String,
579}
580
581#[derive(Debug, Clone, Serialize, Deserialize)]
582#[serde(rename_all = "camelCase")]
583pub struct EventBridgeDeliveries {
584    pub lambda: Vec<EventBridgeLambdaDelivery>,
585    pub logs: Vec<EventBridgeLogDelivery>,
586}
587
588#[derive(Debug, Clone, Serialize, Deserialize)]
589#[serde(rename_all = "camelCase")]
590pub struct EventHistoryResponse {
591    pub events: Vec<EventBridgeEvent>,
592    pub deliveries: EventBridgeDeliveries,
593}
594
595#[derive(Debug, Clone, Serialize, Deserialize)]
596#[serde(rename_all = "camelCase")]
597pub struct FireRuleRequest {
598    pub bus_name: Option<String>,
599    pub rule_name: String,
600}
601
602// ── RDS aws_lambda extension bridge ─────────────────────────────────
603
604/// Request body for `POST /_fakecloud/rds/lambda-invoke`. The endpoint is
605/// the bridge that the PostgreSQL `aws_lambda` extension calls into from
606/// inside an RDS DB instance container — it's normally not driven by
607/// user code directly.
608#[derive(Debug, Clone, Serialize, Deserialize)]
609#[serde(rename_all = "snake_case")]
610pub struct RdsLambdaInvokeRequest {
611    pub function_name: String,
612    pub payload: Option<serde_json::Value>,
613    pub invocation_type: Option<String>,
614    pub region: Option<String>,
615}
616
617/// Shape returned by the bridge — mirrors what `aws_lambda.invoke()`
618/// returns to SQL callers (RDS/Aurora-compatible).
619#[derive(Debug, Clone, Serialize, Deserialize)]
620#[serde(rename_all = "snake_case")]
621pub struct RdsLambdaInvokeResponse {
622    pub status_code: i32,
623    pub payload: Option<serde_json::Value>,
624    pub executed_version: Option<String>,
625    pub log_result: Option<String>,
626}
627
628// ── RDS aws_s3 extension bridge ─────────────────────────────────────
629
630/// Request body for `POST /_fakecloud/rds/s3-import`. The endpoint is
631/// the bridge that the PostgreSQL `aws_s3` extension calls into to
632/// fetch an object from a fakecloud bucket. Body is returned base64
633/// encoded so JSON transport stays text-only.
634#[derive(Debug, Clone, Serialize, Deserialize)]
635#[serde(rename_all = "snake_case")]
636pub struct RdsS3ImportRequest {
637    pub bucket: String,
638    pub key: String,
639    pub region: Option<String>,
640}
641
642#[derive(Debug, Clone, Serialize, Deserialize)]
643#[serde(rename_all = "snake_case")]
644pub struct RdsS3ImportResponse {
645    pub bucket: String,
646    pub key: String,
647    pub body_b64: String,
648    pub bytes_processed: i64,
649}
650
651/// Request body for `POST /_fakecloud/rds/s3-export`. Bridge equivalent
652/// of an S3 PutObject driven from inside the DB container.
653#[derive(Debug, Clone, Serialize, Deserialize)]
654#[serde(rename_all = "snake_case")]
655pub struct RdsS3ExportRequest {
656    pub bucket: String,
657    pub key: String,
658    pub region: Option<String>,
659    pub body_b64: String,
660}
661
662#[derive(Debug, Clone, Serialize, Deserialize)]
663#[serde(rename_all = "snake_case")]
664pub struct RdsS3ExportResponse {
665    pub bucket: String,
666    pub key: String,
667    pub bytes_uploaded: i64,
668}
669
670#[derive(Debug, Clone, Serialize, Deserialize)]
671#[serde(rename_all = "camelCase")]
672pub struct FireRuleTarget {
673    #[serde(rename = "type")]
674    pub target_type: String,
675    pub arn: String,
676}
677
678#[derive(Debug, Clone, Serialize, Deserialize)]
679#[serde(rename_all = "camelCase")]
680pub struct FireRuleResponse {
681    pub targets: Vec<FireRuleTarget>,
682}
683
684// ── Scheduler (EventBridge Scheduler) ───────────────────────────────
685
686#[derive(Debug, Clone, Serialize, Deserialize)]
687#[serde(rename_all = "camelCase")]
688pub struct SchedulerSchedule {
689    pub account_id: String,
690    pub group_name: String,
691    pub name: String,
692    pub arn: String,
693    pub state: String,
694    pub schedule_expression: String,
695    pub target_arn: String,
696    pub last_fired: Option<String>,
697}
698
699#[derive(Debug, Clone, Serialize, Deserialize)]
700#[serde(rename_all = "camelCase")]
701pub struct SchedulerSchedulesResponse {
702    pub schedules: Vec<SchedulerSchedule>,
703}
704
705#[derive(Debug, Clone, Serialize, Deserialize)]
706#[serde(rename_all = "camelCase")]
707pub struct FireScheduleResponse {
708    pub schedule_arn: String,
709    pub target_arn: String,
710}
711
712// ── S3 ──────────────────────────────────────────────────────────────
713
714#[derive(Debug, Clone, Serialize, Deserialize)]
715#[serde(rename_all = "camelCase")]
716pub struct S3Notification {
717    pub bucket: String,
718    pub key: String,
719    pub event_type: String,
720    pub timestamp: String,
721}
722
723#[derive(Debug, Clone, Serialize, Deserialize)]
724#[serde(rename_all = "camelCase")]
725pub struct S3NotificationsResponse {
726    pub notifications: Vec<S3Notification>,
727}
728
729#[derive(Debug, Clone, Serialize, Deserialize)]
730#[serde(rename_all = "camelCase")]
731pub struct LifecycleTickResponse {
732    pub processed_buckets: u64,
733    pub expired_objects: u64,
734    pub transitioned_objects: u64,
735}
736
737#[derive(Debug, Clone, Serialize, Deserialize)]
738#[serde(rename_all = "camelCase")]
739pub struct S3AccessPointEntry {
740    pub name: String,
741    pub alias: String,
742    pub bucket: String,
743    pub account_id: String,
744    pub network_origin: String,
745    #[serde(skip_serializing_if = "Option::is_none")]
746    pub vpc_configuration: Option<String>,
747    #[serde(skip_serializing_if = "Option::is_none")]
748    pub public_access_block: Option<String>,
749    pub created_at: String,
750}
751
752#[derive(Debug, Clone, Serialize, Deserialize)]
753#[serde(rename_all = "camelCase")]
754pub struct S3AccessPointsResponse {
755    pub access_points: Vec<S3AccessPointEntry>,
756}
757
758#[derive(Debug, Clone, Serialize, Deserialize)]
759#[serde(rename_all = "camelCase")]
760pub struct S3ObjectLambdaResponse {
761    pub request_token: String,
762    pub request_route: String,
763    #[serde(skip_serializing_if = "Option::is_none")]
764    pub status_code: Option<u16>,
765    pub body_base64: String,
766    pub body_size: u64,
767    #[serde(skip_serializing_if = "Option::is_none")]
768    pub content_type: Option<String>,
769    #[serde(skip_serializing_if = "Option::is_none")]
770    pub error_message: Option<String>,
771    pub metadata: std::collections::BTreeMap<String, String>,
772}
773
774#[derive(Debug, Clone, Serialize, Deserialize)]
775#[serde(rename_all = "camelCase")]
776pub struct S3ObjectLambdaResponsesResponse {
777    pub responses: Vec<S3ObjectLambdaResponse>,
778}
779
780// ── DynamoDB ────────────────────────────────────────────────────────
781
782#[derive(Debug, Clone, Serialize, Deserialize)]
783#[serde(rename_all = "camelCase")]
784pub struct TtlTickResponse {
785    pub expired_items: u64,
786}
787
788// ── SecretsManager ──────────────────────────────────────────────────
789
790#[derive(Debug, Clone, Serialize, Deserialize)]
791#[serde(rename_all = "camelCase")]
792pub struct RotationTickResponse {
793    pub rotated_secrets: Vec<String>,
794}
795
796// ── ElastiCache ─────────────────────────────────────────────────────
797
798#[derive(Debug, Clone, Serialize, Deserialize)]
799#[serde(rename_all = "camelCase")]
800pub struct ElastiCacheCluster {
801    pub cache_cluster_id: String,
802    pub cache_cluster_status: String,
803    pub engine: String,
804    pub engine_version: String,
805    pub cache_node_type: String,
806    pub num_cache_nodes: i32,
807    pub replication_group_id: Option<String>,
808    pub port: Option<i32>,
809    pub host_port: Option<u16>,
810    pub container_id: Option<String>,
811}
812
813#[derive(Debug, Clone, Serialize, Deserialize)]
814#[serde(rename_all = "camelCase")]
815pub struct ElastiCacheClustersResponse {
816    pub clusters: Vec<ElastiCacheCluster>,
817}
818
819#[derive(Debug, Clone, Serialize, Deserialize)]
820#[serde(rename_all = "camelCase")]
821pub struct ElastiCacheReplicationGroupIntrospection {
822    pub replication_group_id: String,
823    pub status: String,
824    pub description: String,
825    pub member_clusters: Vec<String>,
826    pub automatic_failover: bool,
827    pub multi_az: bool,
828    pub engine: String,
829    pub engine_version: String,
830    pub cache_node_type: String,
831    pub num_cache_clusters: i32,
832}
833
834#[derive(Debug, Clone, Serialize, Deserialize)]
835#[serde(rename_all = "camelCase")]
836pub struct ElastiCacheReplicationGroupsResponse {
837    pub replication_groups: Vec<ElastiCacheReplicationGroupIntrospection>,
838}
839
840#[derive(Debug, Clone, Serialize, Deserialize)]
841#[serde(rename_all = "camelCase")]
842pub struct ElastiCacheServerlessCacheIntrospection {
843    pub serverless_cache_name: String,
844    pub status: String,
845    pub engine: String,
846    pub engine_version: String,
847    pub cache_node_type: Option<String>,
848}
849
850#[derive(Debug, Clone, Serialize, Deserialize)]
851#[serde(rename_all = "camelCase")]
852pub struct ElastiCacheServerlessCachesResponse {
853    pub serverless_caches: Vec<ElastiCacheServerlessCacheIntrospection>,
854}
855
856#[derive(Debug, Clone, Serialize, Deserialize)]
857#[serde(rename_all = "camelCase")]
858pub struct ElastiCacheAclUser {
859    pub name: String,
860    pub status: String,
861    pub access_string: String,
862    pub no_password_required: bool,
863    pub password_count: i32,
864}
865
866#[derive(Debug, Clone, Serialize, Deserialize)]
867#[serde(rename_all = "camelCase")]
868pub struct ElastiCacheAclGroup {
869    pub name: String,
870    pub members: Vec<String>,
871}
872
873#[derive(Debug, Clone, Serialize, Deserialize)]
874#[serde(rename_all = "camelCase")]
875pub struct ElastiCacheAclCluster {
876    pub cluster_id: String,
877    pub engine: String,
878    pub users: Vec<ElastiCacheAclUser>,
879    pub groups: Vec<ElastiCacheAclGroup>,
880}
881
882#[derive(Debug, Clone, Serialize, Deserialize)]
883#[serde(rename_all = "camelCase")]
884pub struct ElastiCacheAclsResponse {
885    pub acls: Vec<ElastiCacheAclCluster>,
886}
887
888// ── Step Functions ──────────────────────────────────────────────────
889
890#[derive(Debug, Clone, Serialize, Deserialize)]
891#[serde(rename_all = "camelCase")]
892pub struct StepFunctionsExecution {
893    pub execution_arn: String,
894    pub state_machine_arn: String,
895    pub name: String,
896    pub status: String,
897    #[serde(skip_serializing_if = "Option::is_none")]
898    pub input: Option<String>,
899    #[serde(skip_serializing_if = "Option::is_none")]
900    pub output: Option<String>,
901    pub start_date: String,
902    #[serde(skip_serializing_if = "Option::is_none")]
903    pub stop_date: Option<String>,
904}
905
906#[derive(Debug, Clone, Serialize, Deserialize)]
907#[serde(rename_all = "camelCase")]
908pub struct StepFunctionsExecutionsResponse {
909    pub executions: Vec<StepFunctionsExecution>,
910}
911
912#[derive(Debug, Clone, Serialize, Deserialize)]
913#[serde(rename_all = "camelCase")]
914pub struct StepFunctionsSyncBillingDetails {
915    pub billed_duration_in_milliseconds: i64,
916    pub billed_memory_used_in_mb: i64,
917}
918
919#[derive(Debug, Clone, Serialize, Deserialize)]
920#[serde(rename_all = "camelCase")]
921pub struct StepFunctionsSyncExecution {
922    pub execution_arn: String,
923    pub state_machine_arn: String,
924    pub name: String,
925    pub status: String,
926    #[serde(skip_serializing_if = "Option::is_none")]
927    pub input: Option<String>,
928    #[serde(skip_serializing_if = "Option::is_none")]
929    pub output: Option<String>,
930    pub started_at: String,
931    #[serde(skip_serializing_if = "Option::is_none")]
932    pub stopped_at: Option<String>,
933    pub duration_ms: i64,
934    pub billing_details: StepFunctionsSyncBillingDetails,
935}
936
937#[derive(Debug, Clone, Serialize, Deserialize)]
938#[serde(rename_all = "camelCase")]
939pub struct StepFunctionsSyncExecutionsResponse {
940    pub executions: Vec<StepFunctionsSyncExecution>,
941}
942
943#[derive(Debug, Clone, Serialize, Deserialize)]
944#[serde(rename_all = "camelCase")]
945pub struct StepFunctionsExecutionTreeNode {
946    pub arn: String,
947    pub state_machine_arn: String,
948    pub status: String,
949    pub started_at: String,
950    #[serde(skip_serializing_if = "Option::is_none")]
951    pub stopped_at: Option<String>,
952    pub children: Vec<StepFunctionsExecutionTreeNode>,
953}
954
955#[derive(Debug, Clone, Serialize, Deserialize)]
956#[serde(rename_all = "camelCase")]
957pub struct StepFunctionsExecutionTreeResponse {
958    pub root_arn: String,
959    pub tree: StepFunctionsExecutionTreeNode,
960}
961
962#[derive(Debug, Clone, Serialize, Deserialize, Default)]
963#[serde(rename_all = "camelCase")]
964pub struct SfnEnqueueActivityTaskRequest {
965    pub activity_arn: String,
966    #[serde(skip_serializing_if = "Option::is_none")]
967    pub input: Option<String>,
968    #[serde(skip_serializing_if = "Option::is_none")]
969    pub heartbeat_seconds: Option<i64>,
970    #[serde(skip_serializing_if = "Option::is_none")]
971    pub timeout_seconds: Option<i64>,
972}
973
974#[derive(Debug, Clone, Serialize, Deserialize)]
975#[serde(rename_all = "camelCase")]
976pub struct SfnEnqueueActivityTaskResponse {
977    pub task_token: String,
978}
979
980// ── Cognito ─────────────────────────────────────────────────────────
981
982#[derive(Debug, Clone, Serialize, Deserialize)]
983#[serde(rename_all = "camelCase")]
984pub struct UserConfirmationCodes {
985    pub confirmation_code: Option<String>,
986    pub attribute_verification_codes: serde_json::Value,
987}
988
989#[derive(Debug, Clone, Serialize, Deserialize)]
990#[serde(rename_all = "camelCase")]
991pub struct ConfirmationCode {
992    pub pool_id: String,
993    pub username: String,
994    pub code: String,
995    #[serde(rename = "type")]
996    pub code_type: String,
997    #[serde(skip_serializing_if = "Option::is_none")]
998    pub attribute: Option<String>,
999}
1000
1001#[derive(Debug, Clone, Serialize, Deserialize)]
1002#[serde(rename_all = "camelCase")]
1003pub struct ConfirmationCodesResponse {
1004    pub codes: Vec<ConfirmationCode>,
1005}
1006
1007#[derive(Debug, Clone, Serialize, Deserialize)]
1008#[serde(rename_all = "camelCase")]
1009pub struct ConfirmUserRequest {
1010    pub user_pool_id: String,
1011    pub username: String,
1012}
1013
1014#[derive(Debug, Clone, Serialize, Deserialize)]
1015#[serde(rename_all = "camelCase")]
1016pub struct ConfirmUserResponse {
1017    pub confirmed: bool,
1018    #[serde(skip_serializing_if = "Option::is_none")]
1019    pub error: Option<String>,
1020}
1021
1022#[derive(Debug, Clone, Serialize, Deserialize)]
1023#[serde(rename_all = "camelCase")]
1024pub struct TokenInfo {
1025    #[serde(rename = "type")]
1026    pub token_type: String,
1027    pub username: String,
1028    pub pool_id: String,
1029    pub client_id: String,
1030    pub issued_at: f64,
1031}
1032
1033#[derive(Debug, Clone, Serialize, Deserialize)]
1034#[serde(rename_all = "camelCase")]
1035pub struct TokensResponse {
1036    pub tokens: Vec<TokenInfo>,
1037}
1038
1039#[derive(Debug, Clone, Serialize, Deserialize)]
1040#[serde(rename_all = "camelCase")]
1041pub struct ExpireTokensRequest {
1042    #[serde(skip_serializing_if = "Option::is_none")]
1043    pub user_pool_id: Option<String>,
1044    #[serde(skip_serializing_if = "Option::is_none")]
1045    pub username: Option<String>,
1046}
1047
1048#[derive(Debug, Clone, Serialize, Deserialize)]
1049#[serde(rename_all = "camelCase")]
1050pub struct ExpireTokensResponse {
1051    pub expired_tokens: u64,
1052}
1053
1054#[derive(Debug, Clone, Serialize, Deserialize)]
1055#[serde(rename_all = "camelCase")]
1056pub struct AuthEvent {
1057    pub event_type: String,
1058    pub username: String,
1059    pub user_pool_id: String,
1060    pub client_id: Option<String>,
1061    pub timestamp: f64,
1062    pub success: bool,
1063}
1064
1065#[derive(Debug, Clone, Serialize, Deserialize)]
1066#[serde(rename_all = "camelCase")]
1067pub struct AuthEventsResponse {
1068    pub events: Vec<AuthEvent>,
1069}
1070
1071/// One PreTokenGeneration Lambda trigger invocation captured for
1072/// introspection at `/_fakecloud/cognito/pretokengen/invocations`.
1073/// `claims_added` / `claims_overridden` / `group_overrides` are
1074/// pre-parsed from the Lambda response so test callers don't have to
1075/// walk the raw `claimsAndScopeOverrideDetails` shape themselves.
1076#[derive(Debug, Clone, Serialize, Deserialize)]
1077#[serde(rename_all = "camelCase")]
1078pub struct PreTokenGenInvocation {
1079    pub pool_id: String,
1080    pub user_pool_arn: String,
1081    pub username: String,
1082    pub trigger_source: String,
1083    pub lambda_arn: String,
1084    pub request_payload: serde_json::Value,
1085    pub response_payload: Option<serde_json::Value>,
1086    pub claims_added: Vec<String>,
1087    pub claims_overridden: Vec<String>,
1088    pub group_overrides: Vec<String>,
1089    /// RFC3339 timestamp.
1090    pub invoked_at: String,
1091    pub duration_ms: u64,
1092}
1093
1094#[derive(Debug, Clone, Serialize, Deserialize)]
1095#[serde(rename_all = "camelCase")]
1096pub struct PreTokenGenInvocationsResponse {
1097    pub invocations: Vec<PreTokenGenInvocation>,
1098}
1099
1100/// Request body for the `/_fakecloud/cognito/authorization-codes` admin
1101/// mint endpoint. Lets test harnesses (and any caller that wants to
1102/// drive the `authorization_code` grant before the Y4 hosted-UI lands)
1103/// pre-allocate the same `(client_id, redirect_uri, scopes, PKCE)`
1104/// binding the real `/oauth2/authorize` endpoint will eventually
1105/// produce.
1106#[derive(Debug, Clone, Serialize, Deserialize)]
1107#[serde(rename_all = "camelCase")]
1108pub struct MintAuthorizationCodeRequest {
1109    pub user_pool_id: String,
1110    pub client_id: String,
1111    pub username: String,
1112    pub redirect_uri: String,
1113    #[serde(default)]
1114    pub scopes: Vec<String>,
1115    #[serde(skip_serializing_if = "Option::is_none")]
1116    pub code_challenge: Option<String>,
1117    #[serde(skip_serializing_if = "Option::is_none")]
1118    pub code_challenge_method: Option<String>,
1119    #[serde(skip_serializing_if = "Option::is_none")]
1120    pub nonce: Option<String>,
1121}
1122
1123#[derive(Debug, Clone, Serialize, Deserialize)]
1124#[serde(rename_all = "camelCase")]
1125pub struct MintAuthorizationCodeResponse {
1126    pub code: String,
1127}
1128
1129// ── API Gateway v2 ──────────────────────────────────────────────────
1130
1131#[derive(Debug, Clone, Serialize, Deserialize)]
1132#[serde(rename_all = "camelCase")]
1133pub struct ApiGatewayV2Request {
1134    pub request_id: String,
1135    pub api_id: String,
1136    pub stage: String,
1137    pub method: String,
1138    pub path: String,
1139    pub headers: std::collections::HashMap<String, String>,
1140    pub query_params: std::collections::HashMap<String, String>,
1141    #[serde(skip_serializing_if = "Option::is_none")]
1142    pub body: Option<String>,
1143    pub timestamp: String,
1144    pub status_code: u16,
1145}
1146
1147#[derive(Debug, Clone, Serialize, Deserialize)]
1148#[serde(rename_all = "camelCase")]
1149pub struct ApiGatewayV2RequestsResponse {
1150    pub requests: Vec<ApiGatewayV2Request>,
1151}
1152
1153// ── Bedrock ────────────────────────────────────────────────────────
1154
1155#[derive(Debug, Clone, Serialize, Deserialize)]
1156#[serde(rename_all = "camelCase")]
1157pub struct BedrockInvocation {
1158    pub model_id: String,
1159    pub input: String,
1160    pub output: String,
1161    pub timestamp: String,
1162    /// Error detail for faulted calls, or `None` on success.
1163    #[serde(default)]
1164    pub error: Option<String>,
1165}
1166
1167#[derive(Debug, Clone, Serialize, Deserialize)]
1168#[serde(rename_all = "camelCase")]
1169pub struct BedrockInvocationsResponse {
1170    pub invocations: Vec<BedrockInvocation>,
1171}
1172
1173#[derive(Debug, Clone, Serialize, Deserialize)]
1174#[serde(rename_all = "camelCase")]
1175pub struct BedrockModelResponseConfig {
1176    pub status: String,
1177    pub model_id: String,
1178}
1179
1180/// One rule in a per-model response rule list.
1181///
1182/// `prompt_contains` is a substring that must appear in the prompt for this
1183/// rule to match. `None` or an empty string matches any prompt.
1184#[derive(Debug, Clone, Serialize, Deserialize)]
1185#[serde(rename_all = "camelCase")]
1186pub struct BedrockResponseRule {
1187    #[serde(default, skip_serializing_if = "Option::is_none")]
1188    pub prompt_contains: Option<String>,
1189    pub response: String,
1190}
1191
1192/// Configuration for a fault to inject on Bedrock runtime calls.
1193#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1194#[serde(rename_all = "camelCase")]
1195pub struct BedrockFaultRule {
1196    pub error_type: String,
1197    #[serde(default, skip_serializing_if = "Option::is_none")]
1198    pub message: Option<String>,
1199    #[serde(default, skip_serializing_if = "Option::is_none")]
1200    pub http_status: Option<u16>,
1201    #[serde(default, skip_serializing_if = "Option::is_none")]
1202    pub count: Option<u32>,
1203    #[serde(default, skip_serializing_if = "Option::is_none")]
1204    pub model_id: Option<String>,
1205    #[serde(default, skip_serializing_if = "Option::is_none")]
1206    pub operation: Option<String>,
1207}
1208
1209/// Server-side view of a queued fault rule.
1210#[derive(Debug, Clone, Serialize, Deserialize)]
1211#[serde(rename_all = "camelCase")]
1212pub struct BedrockFaultRuleState {
1213    pub error_type: String,
1214    pub message: String,
1215    pub http_status: u16,
1216    pub remaining: u32,
1217    #[serde(default)]
1218    pub model_id: Option<String>,
1219    #[serde(default)]
1220    pub operation: Option<String>,
1221}
1222
1223#[derive(Debug, Clone, Serialize, Deserialize)]
1224#[serde(rename_all = "camelCase")]
1225pub struct BedrockFaultsResponse {
1226    pub faults: Vec<BedrockFaultRuleState>,
1227}
1228
1229#[derive(Debug, Clone, Serialize, Deserialize)]
1230#[serde(rename_all = "camelCase")]
1231pub struct BedrockStatusResponse {
1232    pub status: String,
1233}
1234
1235#[derive(Debug, Clone, Serialize, Deserialize)]
1236#[serde(rename_all = "camelCase")]
1237pub struct BedrockAgentAliasSummary {
1238    pub alias_id: String,
1239    pub alias_name: String,
1240    pub agent_version: String,
1241    pub alias_arn: String,
1242    pub status: String,
1243    pub created_at: String,
1244    pub updated_at: String,
1245}
1246
1247#[derive(Debug, Clone, Serialize, Deserialize)]
1248#[serde(rename_all = "camelCase")]
1249pub struct BedrockAgentVersionSummary {
1250    pub agent_version: String,
1251    pub created_at: String,
1252    pub instruction: Option<String>,
1253    pub foundation_model: Option<String>,
1254}
1255
1256#[derive(Debug, Clone, Serialize, Deserialize)]
1257#[serde(rename_all = "camelCase")]
1258pub struct BedrockAgentKnowledgeBaseSummary {
1259    pub knowledge_base_id: String,
1260    pub state: String,
1261    pub description: Option<String>,
1262}
1263
1264#[derive(Debug, Clone, Serialize, Deserialize)]
1265#[serde(rename_all = "camelCase")]
1266pub struct BedrockAgentCollaboratorSummary {
1267    pub collaborator_id: String,
1268    pub collaborator_name: String,
1269    pub collaborator_alias_arn: String,
1270    pub relay_conversation_history: String,
1271}
1272
1273#[derive(Debug, Clone, Serialize, Deserialize)]
1274#[serde(rename_all = "camelCase")]
1275pub struct BedrockAgentRow {
1276    pub agent_id: String,
1277    pub agent_name: String,
1278    pub agent_arn: String,
1279    pub agent_status: String,
1280    pub foundation_model: Option<String>,
1281    pub instruction: Option<String>,
1282    pub knowledge_bases: Vec<BedrockAgentKnowledgeBaseSummary>,
1283    pub action_groups: Vec<serde_json::Value>,
1284    pub collaborators: Vec<BedrockAgentCollaboratorSummary>,
1285    pub aliases: Vec<BedrockAgentAliasSummary>,
1286    pub versions: Vec<BedrockAgentVersionSummary>,
1287    pub prompt_overrides: Option<serde_json::Value>,
1288    pub created_at: String,
1289    pub updated_at: String,
1290}
1291
1292#[derive(Debug, Clone, Serialize, Deserialize)]
1293#[serde(rename_all = "camelCase")]
1294pub struct BedrockAgentAgentsResponse {
1295    pub agents: Vec<BedrockAgentRow>,
1296}
1297
1298#[derive(Debug, Clone, Serialize, Deserialize)]
1299#[serde(rename_all = "camelCase")]
1300pub struct BedrockAgentRuntimeInvocation {
1301    pub invocation_id: String,
1302    pub op: String,
1303    pub agent_id: Option<String>,
1304    pub flow_id: Option<String>,
1305    pub session_id: Option<String>,
1306    pub input: String,
1307    pub output: String,
1308    pub output_chunks: u32,
1309    pub trace: Option<serde_json::Value>,
1310    #[serde(default)]
1311    pub citations: Vec<serde_json::Value>,
1312    pub invoked_at: String,
1313    pub duration_ms: u64,
1314}
1315
1316#[derive(Debug, Clone, Serialize, Deserialize)]
1317#[serde(rename_all = "camelCase")]
1318pub struct BedrockAgentRuntimeInvocationsResponse {
1319    pub invocations: Vec<BedrockAgentRuntimeInvocation>,
1320}
1321
1322#[derive(Debug, Clone, Serialize, Deserialize)]
1323#[serde(rename_all = "camelCase")]
1324pub struct EcrRepository {
1325    pub repository_name: String,
1326    pub repository_arn: String,
1327    pub registry_id: String,
1328    pub repository_uri: String,
1329    pub image_tag_mutability: String,
1330    pub scan_on_push: bool,
1331    pub created_at: String,
1332    pub tags: Vec<EcrTag>,
1333    pub has_policy: bool,
1334    pub has_lifecycle_policy: bool,
1335    pub image_count: u64,
1336    pub layer_count: u64,
1337}
1338
1339#[derive(Debug, Clone, Serialize, Deserialize)]
1340#[serde(rename_all = "camelCase")]
1341pub struct EcrImage {
1342    pub repository_name: String,
1343    pub image_digest: String,
1344    pub image_tags: Vec<String>,
1345    pub image_size_in_bytes: u64,
1346    pub image_manifest_media_type: String,
1347    pub image_pushed_at: String,
1348}
1349
1350#[derive(Debug, Clone, Serialize, Deserialize)]
1351#[serde(rename_all = "camelCase")]
1352pub struct EcrImagesResponse {
1353    pub images: Vec<EcrImage>,
1354}
1355
1356#[derive(Debug, Clone, Serialize, Deserialize)]
1357#[serde(rename_all = "camelCase")]
1358pub struct EcrPullThroughRule {
1359    pub ecr_repository_prefix: String,
1360    pub upstream_registry_url: String,
1361    pub upstream_registry: Option<String>,
1362    pub credential_arn: Option<String>,
1363    pub custom_role_arn: Option<String>,
1364    pub created_at: String,
1365    pub updated_at: String,
1366}
1367
1368#[derive(Debug, Clone, Serialize, Deserialize)]
1369#[serde(rename_all = "camelCase")]
1370pub struct EcrPullThroughRulesResponse {
1371    pub rules: Vec<EcrPullThroughRule>,
1372}
1373
1374#[derive(Debug, Clone, Serialize, Deserialize)]
1375#[serde(rename_all = "camelCase")]
1376pub struct EcrTag {
1377    pub key: String,
1378    pub value: String,
1379}
1380
1381#[derive(Debug, Clone, Serialize, Deserialize)]
1382#[serde(rename_all = "camelCase")]
1383pub struct EcrRepositoriesResponse {
1384    pub repositories: Vec<EcrRepository>,
1385}
1386
1387#[derive(Debug, Clone, Serialize, Deserialize)]
1388#[serde(rename_all = "camelCase")]
1389pub struct EcsCluster {
1390    pub cluster_name: String,
1391    pub cluster_arn: String,
1392    pub status: String,
1393    pub running_tasks_count: i32,
1394    pub pending_tasks_count: i32,
1395    pub active_services_count: i32,
1396    pub registered_container_instances_count: i32,
1397    pub capacity_providers: Vec<String>,
1398    pub tags: Vec<EcsTag>,
1399    pub created_at: String,
1400}
1401
1402#[derive(Debug, Clone, Serialize, Deserialize)]
1403#[serde(rename_all = "camelCase")]
1404pub struct EcsTag {
1405    pub key: String,
1406    pub value: String,
1407}
1408
1409#[derive(Debug, Clone, Serialize, Deserialize)]
1410#[serde(rename_all = "camelCase")]
1411pub struct EcsClustersResponse {
1412    pub clusters: Vec<EcsCluster>,
1413}
1414
1415#[derive(Debug, Clone, Serialize, Deserialize)]
1416#[serde(rename_all = "camelCase")]
1417pub struct EcsTaskContainer {
1418    pub name: String,
1419    pub image: String,
1420    pub last_status: String,
1421    pub exit_code: Option<i64>,
1422    pub runtime_id: Option<String>,
1423    pub essential: bool,
1424}
1425
1426#[derive(Debug, Clone, Serialize, Deserialize)]
1427#[serde(rename_all = "camelCase")]
1428pub struct EcsTask {
1429    pub task_arn: String,
1430    pub task_id: String,
1431    pub cluster_arn: String,
1432    pub cluster_name: String,
1433    pub task_definition_arn: String,
1434    pub family: String,
1435    pub revision: i32,
1436    pub last_status: String,
1437    pub desired_status: String,
1438    pub launch_type: String,
1439    pub created_at: String,
1440    pub started_at: Option<String>,
1441    pub stopping_at: Option<String>,
1442    pub stopped_at: Option<String>,
1443    pub stop_code: Option<String>,
1444    pub stopped_reason: Option<String>,
1445    pub group: Option<String>,
1446    pub containers: Vec<EcsTaskContainer>,
1447    pub captured_log_bytes: usize,
1448}
1449
1450#[derive(Debug, Clone, Serialize, Deserialize)]
1451#[serde(rename_all = "camelCase")]
1452pub struct EcsTasksResponse {
1453    pub tasks: Vec<EcsTask>,
1454}
1455
1456#[derive(Debug, Clone, Serialize, Deserialize)]
1457#[serde(rename_all = "camelCase")]
1458pub struct EcsTaskLogsResponse {
1459    pub task_arn: String,
1460    pub logs: String,
1461    pub last_status: String,
1462    pub exit_code: Option<i64>,
1463}
1464
1465#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1466#[serde(rename_all = "camelCase")]
1467pub struct EcsMarkFailedRequest {
1468    pub exit_code: Option<i64>,
1469    pub reason: Option<String>,
1470}
1471
1472#[derive(Debug, Clone, Serialize, Deserialize)]
1473#[serde(rename_all = "camelCase")]
1474pub struct EcsLifecycleEvent {
1475    pub at: String,
1476    pub event_type: String,
1477    pub task_arn: Option<String>,
1478    pub cluster_arn: Option<String>,
1479    pub last_status: Option<String>,
1480    pub detail: serde_json::Value,
1481}
1482
1483#[derive(Debug, Clone, Serialize, Deserialize)]
1484#[serde(rename_all = "camelCase")]
1485pub struct EcsEventsResponse {
1486    pub events: Vec<EcsLifecycleEvent>,
1487}
1488
1489#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1490#[serde(rename_all = "camelCase")]
1491pub struct EcsTaskMetadataLimits {
1492    pub cpu: Option<f64>,
1493    pub memory: Option<i64>,
1494}
1495
1496#[derive(Debug, Clone, Serialize, Deserialize)]
1497#[serde(rename_all = "camelCase")]
1498pub struct EcsTaskMetadataPort {
1499    #[serde(skip_serializing_if = "Option::is_none")]
1500    pub container_port: Option<i64>,
1501    #[serde(skip_serializing_if = "Option::is_none")]
1502    pub host_port: Option<i64>,
1503    #[serde(skip_serializing_if = "Option::is_none")]
1504    pub protocol: Option<String>,
1505}
1506
1507#[derive(Debug, Clone, Serialize, Deserialize)]
1508#[serde(rename_all = "camelCase")]
1509pub struct EcsTaskMetadataContainer {
1510    pub name: String,
1511    pub image: String,
1512    #[serde(skip_serializing_if = "Option::is_none")]
1513    pub image_id: Option<String>,
1514    pub ports: Vec<EcsTaskMetadataPort>,
1515    pub labels: std::collections::BTreeMap<String, String>,
1516    pub desired_status: String,
1517    pub known_status: String,
1518    pub limits: EcsTaskMetadataLimits,
1519    #[serde(skip_serializing_if = "Option::is_none")]
1520    pub created_at: Option<String>,
1521    #[serde(skip_serializing_if = "Option::is_none")]
1522    pub started_at: Option<String>,
1523    #[serde(skip_serializing_if = "Option::is_none")]
1524    pub exit_code: Option<i64>,
1525}
1526
1527#[derive(Debug, Clone, Serialize, Deserialize)]
1528#[serde(rename_all = "camelCase")]
1529pub struct EcsTaskMetadata {
1530    pub cluster: String,
1531    pub task_arn: String,
1532    pub family: String,
1533    pub revision: i32,
1534    pub desired_status: String,
1535    pub known_status: String,
1536    pub containers: Vec<EcsTaskMetadataContainer>,
1537    #[serde(skip_serializing_if = "Option::is_none")]
1538    pub pull_started_at: Option<String>,
1539    #[serde(skip_serializing_if = "Option::is_none")]
1540    pub pull_stopped_at: Option<String>,
1541    pub availability_zone: String,
1542    pub launch_type: String,
1543    #[serde(skip_serializing_if = "Option::is_none")]
1544    pub vpc_id: Option<String>,
1545    #[serde(skip_serializing_if = "Option::is_none")]
1546    pub eni_id: Option<String>,
1547}
1548
1549#[derive(Debug, Clone, Serialize, Deserialize)]
1550#[serde(rename_all = "camelCase")]
1551pub struct EcsTaskMetadataResponse {
1552    pub task: EcsTaskMetadata,
1553}
1554
1555// ── ELBv2 ───────────────────────────────────────────────────────────
1556
1557#[derive(Debug, Clone, Serialize, Deserialize)]
1558#[serde(rename_all = "camelCase")]
1559pub struct Elbv2LoadBalancer {
1560    pub arn: String,
1561    pub name: String,
1562    pub dns_name: String,
1563    pub scheme: String,
1564    pub vpc_id: String,
1565    pub state_code: String,
1566    pub state_reason: Option<String>,
1567    pub lb_type: String,
1568    pub ip_address_type: String,
1569    pub availability_zones: Vec<Elbv2AvailabilityZone>,
1570    pub security_groups: Vec<String>,
1571    pub created_time: String,
1572    pub tags: Vec<Elbv2Tag>,
1573    /// In-process data plane TCP port for ALBs. `None` for NLB/GWLB
1574    /// or when the data plane is disabled. Tests connect to
1575    /// `127.0.0.1:<bound_port>` to reach the routed targets.
1576    #[serde(skip_serializing_if = "Option::is_none")]
1577    pub bound_port: Option<u16>,
1578}
1579
1580#[derive(Debug, Clone, Serialize, Deserialize)]
1581#[serde(rename_all = "camelCase")]
1582pub struct Elbv2AvailabilityZone {
1583    pub zone_name: String,
1584    pub subnet_id: String,
1585}
1586
1587#[derive(Debug, Clone, Serialize, Deserialize)]
1588#[serde(rename_all = "camelCase")]
1589pub struct Elbv2Tag {
1590    pub key: String,
1591    pub value: String,
1592}
1593
1594#[derive(Debug, Clone, Serialize, Deserialize)]
1595#[serde(rename_all = "camelCase")]
1596pub struct Elbv2LoadBalancersResponse {
1597    pub load_balancers: Vec<Elbv2LoadBalancer>,
1598}
1599
1600#[derive(Debug, Clone, Serialize, Deserialize)]
1601#[serde(rename_all = "camelCase")]
1602pub struct Elbv2TargetGroup {
1603    pub arn: String,
1604    pub name: String,
1605    pub protocol: Option<String>,
1606    pub port: Option<i32>,
1607    pub vpc_id: Option<String>,
1608    pub target_type: String,
1609    pub load_balancer_arns: Vec<String>,
1610    pub targets: Vec<Elbv2Target>,
1611    pub health_check_protocol: Option<String>,
1612    pub health_check_port: Option<String>,
1613    pub health_check_path: Option<String>,
1614    pub healthy_threshold_count: i32,
1615    pub unhealthy_threshold_count: i32,
1616    pub created_time: String,
1617    pub tags: Vec<Elbv2Tag>,
1618}
1619
1620#[derive(Debug, Clone, Serialize, Deserialize)]
1621#[serde(rename_all = "camelCase")]
1622pub struct Elbv2Target {
1623    pub id: String,
1624    pub port: Option<i32>,
1625    pub availability_zone: Option<String>,
1626    pub health_state: String,
1627    pub health_reason: Option<String>,
1628    pub health_description: Option<String>,
1629}
1630
1631#[derive(Debug, Clone, Serialize, Deserialize)]
1632#[serde(rename_all = "camelCase")]
1633pub struct Elbv2TargetGroupsResponse {
1634    pub target_groups: Vec<Elbv2TargetGroup>,
1635}
1636
1637#[derive(Debug, Clone, Serialize, Deserialize)]
1638#[serde(rename_all = "camelCase")]
1639pub struct Elbv2Listener {
1640    pub arn: String,
1641    pub load_balancer_arn: String,
1642    pub port: Option<i32>,
1643    pub protocol: Option<String>,
1644    pub ssl_policy: Option<String>,
1645    pub certificate_arns: Vec<String>,
1646    pub default_action_type: Option<String>,
1647    pub default_target_group_arn: Option<String>,
1648}
1649
1650#[derive(Debug, Clone, Serialize, Deserialize)]
1651#[serde(rename_all = "camelCase")]
1652pub struct Elbv2ListenersResponse {
1653    pub listeners: Vec<Elbv2Listener>,
1654}
1655
1656#[derive(Debug, Clone, Serialize, Deserialize)]
1657#[serde(rename_all = "camelCase")]
1658pub struct Elbv2Rule {
1659    pub arn: String,
1660    pub listener_arn: String,
1661    pub priority: String,
1662    pub is_default: bool,
1663    pub condition_fields: Vec<String>,
1664    pub action_type: Option<String>,
1665}
1666
1667#[derive(Debug, Clone, Serialize, Deserialize)]
1668#[serde(rename_all = "camelCase")]
1669pub struct Elbv2RulesResponse {
1670    pub rules: Vec<Elbv2Rule>,
1671}
1672
1673/// Request to bootstrap an IAM admin user in a specific account.
1674/// Used by `/_fakecloud/iam/create-admin` to solve the multi-account
1675/// bootstrap problem: there's no per-account root credential, so this
1676/// endpoint creates a user with full admin access in any account.
1677#[derive(Debug, Clone, Serialize, Deserialize)]
1678#[serde(rename_all = "camelCase")]
1679pub struct CreateAdminRequest {
1680    pub account_id: String,
1681    pub user_name: String,
1682}
1683
1684#[derive(Debug, Clone, Serialize, Deserialize)]
1685#[serde(rename_all = "camelCase")]
1686pub struct CreateAdminResponse {
1687    pub access_key_id: String,
1688    pub secret_access_key: String,
1689    pub account_id: String,
1690    pub arn: String,
1691}
1692
1693/// Body for `POST /_fakecloud/route53/health-checks/{id}/status`. The
1694/// admin endpoint flips a stored Route 53 health check's reported
1695/// status (and optionally the last-failure-reason observation) so
1696/// tests can simulate failover scenarios without a live checker.
1697#[derive(Debug, Clone, Serialize, Deserialize)]
1698#[serde(rename_all = "camelCase")]
1699pub struct Route53HealthCheckStatusRequest {
1700    /// New status reported by `GetHealthCheckStatus`. One of
1701    /// `"Success"`, `"Failure"`, `"Timeout"`, `"DnsError"`,
1702    /// `"InsufficientDataPoints"`, `"Unknown"`.
1703    pub status: Route53HealthCheckStatusValue,
1704    /// Optional last-failure observation surfaced by
1705    /// `GetHealthCheckLastFailureReason` and appended to the
1706    /// `<Status>` element for failure-flavoured statuses (`Failure`,
1707    /// `Timeout`, `DnsError`). Ignored when `status` is `Success`,
1708    /// `InsufficientDataPoints`, or `Unknown`. `None` leaves the prior
1709    /// value intact.
1710    #[serde(default)]
1711    pub reason: Option<String>,
1712}
1713
1714/// Discriminator for the admin `status` field. Mirrors the variants of
1715/// `fakecloud_route53::HealthCheckStatus` without forcing the SDK crate
1716/// to depend on the route53 crate.
1717#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1718pub enum Route53HealthCheckStatusValue {
1719    Success,
1720    Failure,
1721    Timeout,
1722    DnsError,
1723    InsufficientDataPoints,
1724    Unknown,
1725}
1726
1727/// Response body for `GET /_fakecloud/route53/zones/{id}/dnssec`. Surfaces
1728/// the deterministic ECDSA P-256 DNSSEC chain-of-trust material for a
1729/// hosted zone with at least one ACTIVE Key Signing Key. Real Route 53
1730/// keeps this material inside KMS; fakecloud derives it from the
1731/// `(zone_id, ksk_name)` pair so persistence reloads, multiple test
1732/// runs, and verifier code see stable values.
1733#[derive(Debug, Clone, Serialize, Deserialize)]
1734#[serde(rename_all = "camelCase")]
1735pub struct Route53DnssecMaterialResponse {
1736    /// Hosted zone the material belongs to (without the
1737    /// `/hostedzone/` prefix).
1738    pub hosted_zone_id: String,
1739    /// KSK name used to derive the keypair.
1740    pub key_signing_key_name: String,
1741    /// Algorithm number (always `13` for ECDSAP256SHA256).
1742    pub algorithm: u8,
1743    /// DNSKEY flags field (always `257` for a KSK).
1744    pub flags: u16,
1745    /// Standard DNSKEY key tag (RFC 4034 Appendix B).
1746    pub key_tag: u16,
1747    /// DNSKEY public-key wire bytes (`X || Y`, 64 bytes for P-256),
1748    /// base64-encoded — what would appear in the DNSKEY RDATA.
1749    pub dnskey_public_key_b64: String,
1750    /// SHA-256 DS digest hex over the canonical owner name + DNSKEY
1751    /// RDATA. Equivalent to what the parent zone publishes.
1752    pub ds_digest_sha256_hex: String,
1753}
1754
1755/// Body for `POST /_fakecloud/route53/zones/{id}/dnssec/sign`. Signs an
1756/// RRset under the zone's first ACTIVE KSK and returns the raw RRSIG
1757/// fields so tests can verify the signature against
1758/// `dnskey_public_key_b64` from `Route53DnssecMaterialResponse`.
1759#[derive(Debug, Clone, Serialize, Deserialize)]
1760#[serde(rename_all = "camelCase")]
1761pub struct Route53DnssecSignRequest {
1762    /// RRset owner name (e.g., `"www.example.com."`). Trailing dot
1763    /// optional — added if missing.
1764    pub name: String,
1765    /// Record type (`"A"`, `"AAAA"`, `"CNAME"`, `"TXT"`, ...).
1766    #[serde(rename = "type")]
1767    pub record_type: String,
1768    /// Original TTL field for the RRSIG.
1769    pub ttl: u32,
1770    /// One-or-more RDATA values matching what `ResourceRecord.Value`
1771    /// would carry on the wire.
1772    pub rdatas: Vec<String>,
1773}
1774
1775/// Response from the DNSSEC sign admin endpoint.
1776#[derive(Debug, Clone, Serialize, Deserialize)]
1777#[serde(rename_all = "camelCase")]
1778pub struct Route53DnssecSignResponse {
1779    /// Base64-encoded raw `r||s` ECDSA-P256 signature (64 bytes
1780    /// decoded).
1781    pub signature_b64: String,
1782    /// Algorithm number (always `13`).
1783    pub algorithm: u8,
1784    /// Key tag of the signing KSK.
1785    pub key_tag: u16,
1786    /// Owner name of the signer (the zone name).
1787    pub signer_name: String,
1788    /// Unix-time inception (signature validity start).
1789    pub inception: u32,
1790    /// Unix-time expiration (signature validity end).
1791    pub expiration: u32,
1792    /// Label count for the RRSIG `Labels` field.
1793    pub labels: u8,
1794    /// Original TTL echoed back from the request.
1795    pub original_ttl: u32,
1796    /// Record type echoed back from the request.
1797    #[serde(rename = "type")]
1798    pub rrset_type: String,
1799}
1800
1801/// Body for `POST /_fakecloud/acm/certificates/{arn-or-id}/status`. The
1802/// admin endpoint flips a stored ACM certificate's status (and
1803/// optionally records a failure reason) so tests can synchronously
1804/// drive a cert to `ISSUED`, `FAILED`, or `VALIDATION_TIMED_OUT`
1805/// without waiting on the auto-issue tick.
1806#[derive(Debug, Clone, Serialize, Deserialize)]
1807#[serde(rename_all = "camelCase")]
1808pub struct AcmCertificateStatusRequest {
1809    /// New certificate status. One of `"ISSUED"`, `"FAILED"`,
1810    /// `"VALIDATION_TIMED_OUT"`. Other ACM statuses are accepted as
1811    /// raw strings in case callers want to simulate a niche state.
1812    pub status: String,
1813    /// Optional failure reason surfaced as `FailureReason` in
1814    /// `DescribeCertificate`. Ignored when `status = ISSUED`. `None`
1815    /// leaves the prior value intact.
1816    #[serde(default)]
1817    pub reason: Option<String>,
1818}
1819
1820// ── Glue ────────────────────────────────────────────────────────────
1821
1822/// Curated row for `GET /_fakecloud/glue/jobs`. Mirrors the
1823/// configured Glue Job state so tests can assert what `CreateJob`
1824/// recorded without re-listing through the AWS surface.
1825#[derive(Debug, Clone, Serialize, Deserialize)]
1826#[serde(rename_all = "camelCase")]
1827pub struct GlueJob {
1828    pub account_id: String,
1829    pub name: String,
1830    pub role: String,
1831    pub command: serde_json::Value,
1832    pub default_arguments: std::collections::BTreeMap<String, String>,
1833    pub max_capacity: Option<f64>,
1834    pub max_retries: i64,
1835    pub timeout: Option<i64>,
1836    pub glue_version: Option<String>,
1837    pub worker_type: Option<String>,
1838    pub number_of_workers: Option<i64>,
1839    pub created_on: String,
1840    pub last_modified_on: String,
1841}
1842
1843// ── Athena ──────────────────────────────────────────────────────────
1844
1845/// One row in the Athena named-query introspection list returned by
1846/// `GET /_fakecloud/athena/named-queries`. Mirrors the underlying named
1847/// query record plus a `last_used_at` timestamp the server bumps every
1848/// time `StartQueryExecution` resolves the query by id.
1849#[derive(Debug, Clone, Serialize, Deserialize)]
1850#[serde(rename_all = "camelCase")]
1851pub struct AthenaNamedQuery {
1852    pub named_query_id: String,
1853    pub name: String,
1854    #[serde(default)]
1855    pub description: Option<String>,
1856    pub database: String,
1857    pub query_string: String,
1858    pub workgroup: String,
1859    /// RFC3339 timestamp of the most recent `StartQueryExecution` that
1860    /// resolved its query string from this named query. `None` until the
1861    /// first such invocation.
1862    #[serde(default)]
1863    pub last_used_at: Option<String>,
1864}
1865
1866#[derive(Debug, Clone, Serialize, Deserialize)]
1867#[serde(rename_all = "camelCase")]
1868pub struct GlueJobsResponse {
1869    pub jobs: Vec<GlueJob>,
1870}
1871
1872/// Curated row for `GET /_fakecloud/glue/job-runs`. Includes the
1873/// full state machine of a JobRun (StartJobRun ledger). Filter by
1874/// `?job_name=foo` to scope to a single job.
1875#[derive(Debug, Clone, Serialize, Deserialize)]
1876#[serde(rename_all = "camelCase")]
1877pub struct GlueJobRun {
1878    pub account_id: String,
1879    pub id: String,
1880    pub job_name: String,
1881    pub attempt: i64,
1882    pub started_on: String,
1883    pub completed_on: Option<String>,
1884    pub job_run_state: String,
1885    pub arguments: std::collections::BTreeMap<String, String>,
1886    pub error_message: Option<String>,
1887    pub execution_time: i64,
1888}
1889
1890// ── Organizations ───────────────────────────────────────────────────
1891
1892/// A single member account as exposed by
1893/// `GET /_fakecloud/organizations/accounts`. Mirrors the AWS
1894/// Organizations `Account` shape but adds two fakecloud-only fields
1895/// useful for test assertions: `parentOuId` (resolved parent OU or
1896/// root) and `scpAttached` (the set of SCP IDs directly attached to
1897/// the account — does not walk up the hierarchy).
1898#[derive(Debug, Clone, Serialize, Deserialize)]
1899#[serde(rename_all = "camelCase")]
1900pub struct OrganizationsAccount {
1901    pub id: String,
1902    pub arn: String,
1903    pub email: String,
1904    pub name: String,
1905    /// AWS lifecycle state. One of `ACTIVE`, `SUSPENDED`,
1906    /// `PENDING_CLOSURE`.
1907    pub status: String,
1908    /// How the account entered the organization. One of `INVITED`,
1909    /// `CREATED`.
1910    pub joined_method: String,
1911    /// RFC3339 timestamp the account joined the org.
1912    pub joined_timestamp: String,
1913    /// Parent OU or root id. Always set for accounts attached to a
1914    /// live org; `None` only if the account record is mid-removal.
1915    #[serde(skip_serializing_if = "Option::is_none")]
1916    pub parent_ou_id: Option<String>,
1917    /// Tags directly attached to the account (alphabetical by key).
1918    #[serde(default)]
1919    pub tags: Vec<OrganizationsTag>,
1920    /// SCP ids directly attached to the account (alphabetical).
1921    /// Does not include policies inherited from parent OUs or root.
1922    #[serde(default)]
1923    pub scp_attached: Vec<String>,
1924}
1925
1926#[derive(Debug, Clone, Serialize, Deserialize)]
1927#[serde(rename_all = "camelCase")]
1928pub struct GlueJobRunsResponse {
1929    pub runs: Vec<GlueJobRun>,
1930}
1931
1932#[derive(Debug, Clone, Serialize, Deserialize)]
1933#[serde(rename_all = "camelCase")]
1934pub struct AthenaNamedQueriesResponse {
1935    pub queries: Vec<AthenaNamedQuery>,
1936}
1937
1938#[derive(Debug, Clone, Serialize, Deserialize)]
1939#[serde(rename_all = "camelCase")]
1940pub struct OrganizationsTag {
1941    pub key: String,
1942    pub value: String,
1943}
1944
1945/// Response body for `GET /_fakecloud/organizations/accounts`.
1946///
1947/// `managementAccountId` and `masterAccountId` are duplicates — AWS
1948/// renamed `Master` to `Management` in 2020 but kept the old field
1949/// around for back-compat. Both are returned here so SDKs in either
1950/// vintage match.
1951///
1952/// When no organization has been created yet, `accounts` is empty and
1953/// the account-id fields are `None`.
1954#[derive(Debug, Clone, Serialize, Deserialize)]
1955#[serde(rename_all = "camelCase")]
1956pub struct OrganizationsAccountsResponse {
1957    pub accounts: Vec<OrganizationsAccount>,
1958    #[serde(skip_serializing_if = "Option::is_none")]
1959    pub management_account_id: Option<String>,
1960    #[serde(skip_serializing_if = "Option::is_none")]
1961    pub master_account_id: Option<String>,
1962}
1963
1964/// Body for `POST /_fakecloud/cloudfront/distributions/{id}/status`. The
1965/// admin endpoint flips a stored CloudFront Distribution's status so
1966/// tests can synchronously force it into `Deployed` or `InProgress`
1967/// without waiting on the propagation tick.
1968#[derive(Debug, Clone, Serialize, Deserialize)]
1969#[serde(rename_all = "camelCase")]
1970pub struct CloudFrontDistributionStatusRequest {
1971    /// New distribution status. Typically `"Deployed"` or `"InProgress"`.
1972    pub status: String,
1973}