diff --git a/AGENTS.md b/AGENTS.md index 0744f56c7..c93a32c27 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,7 +5,7 @@ Local AWS cloud emulator. Part of the faisca project family. ## Product Context - FakeCloud is a local AWS emulator focused on high-fidelity behavior and AWS-compatible responses. -- Current project state: 105 AWS services, 7,505 operations, 248,557/248,557 Smithy conformance variants pass — true 100% across every implemented service, no flake margin. See [the parity matrix](website/content/docs/parity.md) for the full service-by-service breakdown of control-plane vs data-plane coverage and known limitations. +- Current project state: 105 AWS services, 7,506 operations, 248,557/248,557 Smithy conformance variants pass — true 100% across every implemented service, no flake margin. See [the parity matrix](website/content/docs/parity.md) for the full service-by-service breakdown of control-plane vs data-plane coverage and known limitations. - The broader roadmap prioritizes services that LocalStack keeps behind paid tiers, especially ECS, ELB/ALB, CloudFront, CloudWatch Metrics, and EC2. - Introspection SDKs (Rust, Python, TypeScript, Go, PHP, Java) are already built and maintained for the `/_fakecloud/*` endpoints. diff --git a/README.md b/README.md index 8722ee501..8ed863550 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Works as a drop-in for LocalStack in CI, with Terraform (`endpoints` block), CDK ## Supported services -105 services, 7,505 operations, and true 100% conformance across every implemented service. +105 services, 7,506 operations, and true 100% conformance across every implemented service. Highlights: S3, DynamoDB, SQS, SNS, EventBridge, Lambda, IAM, STS, KMS, Secrets Manager, CloudFormation, SES, Cognito, Kinesis, RDS (6 real engines), ElastiCache, ECS/ECR, EC2, Step Functions, API Gateway v1/v2, Bedrock, and 80+ more. diff --git a/aws-models/cloudtrail.json b/aws-models/cloudtrail.json index 33ca8fe6b..18921dbb0 100644 --- a/aws-models/cloudtrail.json +++ b/aws-models/cloudtrail.json @@ -420,7 +420,7 @@ } ], "traits": { - "smithy.api#documentation": "

Cancels a query if the query is not in a terminated state, such as\n CANCELLED, FAILED, TIMED_OUT, or\n FINISHED. You must specify an ARN value for EventDataStore.\n The ID of the query that you want to cancel is also required. When you run\n CancelQuery, the query status might show as CANCELLED even if\n the operation is not yet finished.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Cancels a query if the query is not in a terminated state, such as\n CANCELLED, FAILED, TIMED_OUT, or\n FINISHED. You must specify an ARN value for EventDataStore.\n The ID of the query that you want to cancel is also required. When you run\n CancelQuery, the query status might show as CANCELLED even if\n the operation is not yet finished.

", "smithy.api#idempotent": {} } }, @@ -2263,7 +2263,7 @@ } ], "traits": { - "smithy.api#documentation": "

Creates a channel for CloudTrail to ingest events from a partner or external source. \n After you create a channel, a CloudTrail Lake event data store can log events \n from the partner or source that you specify.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Creates a channel for CloudTrail to ingest events from a partner or external source. \n After you create a channel, a CloudTrail Lake event data store can log events \n from the partner or source that you specify.

" } }, "com.amazonaws.cloudtrail#CreateChannelRequest": { @@ -2368,7 +2368,7 @@ } ], "traits": { - "smithy.api#documentation": "

\nCreates a custom dashboard or the Highlights dashboard.\n

\n \n

\n CloudTrail runs queries to populate the dashboard's widgets during a manual or scheduled refresh. CloudTrail must be granted permissions to run the StartQuery operation on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to each event data store. For more information, \n see Example: Allow CloudTrail to run queries to populate a dashboard in the CloudTrail User Guide.\n

\n

\n To set a refresh schedule, CloudTrail must be granted permissions to run the StartDashboardRefresh operation to refresh the dashboard on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to the dashboard. For more information, \n see \n Resource-based policy example for a dashboard in the CloudTrail User Guide.\n

\n

For more information about dashboards, see CloudTrail Lake dashboards in the CloudTrail User Guide.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\nCreates a custom dashboard or the Highlights dashboard.\n

\n \n

\n CloudTrail runs queries to populate the dashboard's widgets during a manual or scheduled refresh. CloudTrail must be granted permissions to run the StartQuery operation on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to each event data store. For more information, \n see Example: Allow CloudTrail to run queries to populate a dashboard in the CloudTrail User Guide.\n

\n

\n To set a refresh schedule, CloudTrail must be granted permissions to run the StartDashboardRefresh operation to refresh the dashboard on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to the dashboard. For more information, \n see \n Resource-based policy example for a dashboard in the CloudTrail User Guide.\n

\n

For more information about dashboards, see CloudTrail Lake dashboards in the CloudTrail User Guide.

", "smithy.api#idempotent": {} } }, @@ -2523,7 +2523,7 @@ } ], "traits": { - "smithy.api#documentation": "

Creates a new event data store.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Creates a new event data store.

" } }, "com.amazonaws.cloudtrail#CreateEventDataStoreRequest": { @@ -2821,7 +2821,7 @@ "IncludeGlobalServiceEvents": { "target": "com.amazonaws.cloudtrail#Boolean", "traits": { - "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the\n log files.

" + "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the\n log files. Setting this value to true only delivers global service events to\n the trail if the trail is multi-Region or if the trail's home Region is the partition leader\n Region (for example, us-east-1).

" } }, "IsMultiRegionTrail": { @@ -2862,6 +2862,12 @@ }, "TagsList": { "target": "com.amazonaws.cloudtrail#TagsList" + }, + "RecursiveLogging": { + "target": "com.amazonaws.cloudtrail#Boolean", + "traits": { + "smithy.api#documentation": "

Specifies whether recursive logging is enabled for the trail. If you set\n RecursiveLogging to false, CloudTrail suppresses\n events generated by CloudTrail when it delivers log files to your trail's\n destinations, including Amazon S3 and CloudWatch Logs. The default value is\n true.

" + } } }, "traits": { @@ -2906,7 +2912,7 @@ "IncludeGlobalServiceEvents": { "target": "com.amazonaws.cloudtrail#Boolean", "traits": { - "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the\n log files.

" + "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the\n log files. Setting this value to true only delivers global service events to\n the trail if the trail is multi-Region or if the trail's home Region is the partition leader\n Region (for example, us-east-1).

" } }, "IsMultiRegionTrail": { @@ -2950,6 +2956,12 @@ "traits": { "smithy.api#documentation": "

Specifies whether the trail is an organization trail.

" } + }, + "RecursiveLogging": { + "target": "com.amazonaws.cloudtrail#Boolean", + "traits": { + "smithy.api#documentation": "

Specifies whether recursive logging is enabled for the trail.

" + } } }, "traits": { @@ -3129,7 +3141,7 @@ } ], "traits": { - "smithy.api#documentation": "

Deletes a channel.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Deletes a channel.

" } }, "com.amazonaws.cloudtrail#DeleteChannelRequest": { @@ -3174,7 +3186,7 @@ } ], "traits": { - "smithy.api#documentation": "

\nDeletes the specified dashboard. You cannot delete a dashboard that has termination protection enabled.\n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\nDeletes the specified dashboard. You cannot delete a dashboard that has termination protection enabled.\n

", "smithy.api#idempotent": {} } }, @@ -3253,7 +3265,7 @@ } ], "traits": { - "smithy.api#documentation": "

Disables the event data store specified by EventDataStore, which accepts an\n event data store ARN. After you run DeleteEventDataStore, the event data store\n enters a PENDING_DELETION state, and is automatically deleted after a wait\n period of seven days. TerminationProtectionEnabled must be set to\n False on the event data store and the FederationStatus must be DISABLED. \n You cannot delete an event data store if TerminationProtectionEnabled \n is True or the FederationStatus is ENABLED.

\n

After you run DeleteEventDataStore on an event data store, you cannot run\n ListQueries, DescribeQuery, or GetQueryResults on\n queries that are using an event data store in a PENDING_DELETION state. An\n event data store in the PENDING_DELETION state does not incur costs.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Disables the event data store specified by EventDataStore, which accepts an\n event data store ARN. After you run DeleteEventDataStore, the event data store\n enters a PENDING_DELETION state, and is automatically deleted after a wait\n period of seven days. TerminationProtectionEnabled must be set to\n False on the event data store and the FederationStatus must be DISABLED. \n You cannot delete an event data store if TerminationProtectionEnabled \n is True or the FederationStatus is ENABLED.

\n

After you run DeleteEventDataStore on an event data store, you cannot run\n ListQueries, DescribeQuery, or GetQueryResults on\n queries that are using an event data store in a PENDING_DELETION state. An\n event data store in the PENDING_DELETION state does not incur costs.

" } }, "com.amazonaws.cloudtrail#DeleteEventDataStoreRequest": { @@ -3584,7 +3596,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns metadata about a query, including query run time in milliseconds, number of\n events scanned and matched, and query status. If the query results were delivered to an S3 bucket, \n the response also provides the S3 URI and the delivery status.

\n

You must specify either QueryId or QueryAlias. Specifying the QueryAlias parameter \n returns information about the last query run for the alias. You can provide \n RefreshId along with QueryAlias to view the query results \n of a dashboard query for the specified RefreshId.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns metadata about a query, including query run time in milliseconds, number of\n events scanned and matched, and query status. If the query results were delivered to an S3 bucket, \n the response also provides the S3 URI and the delivery status.

\n

You must specify either QueryId or QueryAlias. Specifying the QueryAlias parameter \n returns information about the last query run for the alias. You can provide \n RefreshId along with QueryAlias to view the query results \n of a dashboard query for the specified RefreshId.

", "smithy.api#idempotent": {} } }, @@ -3874,7 +3886,7 @@ } ], "traits": { - "smithy.api#documentation": "

\n Disables Lake query federation on the specified event data store. When you disable federation, CloudTrail disables \n the integration with Glue, Lake Formation, and Amazon Athena. \n After disabling Lake query federation, you can no longer query your event data in Amazon Athena.

\n

No CloudTrail Lake data is deleted when you disable federation and you can continue to run queries in CloudTrail Lake.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\n Disables Lake query federation on the specified event data store. When you disable federation, CloudTrail disables \n the integration with Glue, Lake Formation, and Amazon Athena. \n After disabling Lake query federation, you can no longer query your event data in Amazon Athena.

\n

No CloudTrail Lake data is deleted when you disable federation and you can continue to run queries in CloudTrail Lake.

" } }, "com.amazonaws.cloudtrail#DisableFederationRequest": { @@ -3971,7 +3983,7 @@ } ], "traits": { - "smithy.api#documentation": "

\n Enables Lake query federation on the specified event data store. Federating an event data store lets you view the metadata associated with the event data store in the Glue \n Data Catalog and run \n SQL queries against your event data using Amazon Athena. The table metadata stored in the Glue Data Catalog \n lets the Athena query engine know how to find, read, and process the data that you want to query.

\n

When you enable Lake query federation, CloudTrail\n creates a managed database named aws:cloudtrail (if the database doesn't already exist) and a managed federated table in\n the Glue Data Catalog. The event data store ID is used for the table name. CloudTrail registers the role ARN and event data store in\n Lake Formation, the service responsible for allowing fine-grained access control \n of the federated resources in the Glue Data Catalog.

\n

For more information about Lake query federation, see Federate an event data store.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\n Enables Lake query federation on the specified event data store. Federating an event data store lets you view the metadata associated with the event data store in the Glue \n Data Catalog and run \n SQL queries against your event data using Amazon Athena. The table metadata stored in the Glue Data Catalog \n lets the Athena query engine know how to find, read, and process the data that you want to query.

\n

When you enable Lake query federation, CloudTrail\n creates a managed database named aws:cloudtrail (if the database doesn't already exist) and a managed federated table in\n the Glue Data Catalog. The event data store ID is used for the table name. CloudTrail registers the role ARN and event data store in\n Lake Formation, the service responsible for allowing fine-grained access control \n of the federated resources in the Glue Data Catalog.

\n

For more information about Lake query federation, see Federate an event data store.

" } }, "com.amazonaws.cloudtrail#EnableFederationRequest": { @@ -4594,7 +4606,7 @@ } ], "traits": { - "smithy.api#documentation": "

\n Generates a query from a natural language prompt. This operation uses generative artificial intelligence\n (generative AI) to produce a ready-to-use SQL query from the prompt.\n

\n

The prompt can be a question or a statement about the event data\n in your event data store. For example, you can enter prompts like \"What are my\n top errors in the past month?\" and \u201cGive me a list of users that used SNS.\u201d

\n

The prompt must be in English. For information about limitations, permissions, and supported Regions, see \n Create CloudTrail Lake queries from natural language prompts \n in the CloudTrail user guide.

\n \n

Do not include any personally identifying, confidential, or sensitive information\n in your prompts.

\n

This feature uses generative AI large language models (LLMs); we recommend double-checking the\n LLM response.

\n
", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\n Generates a query from a natural language prompt. This operation uses generative artificial intelligence\n (generative AI) to produce a ready-to-use SQL query from the prompt.\n

\n

The prompt can be a question or a statement about the event data\n in your event data store. For example, you can enter prompts like \"What are my\n top errors in the past month?\" and \u201cGive me a list of users that used SNS.\u201d

\n

The prompt must be in English. For information about limitations, permissions, and supported Regions, see \n Create CloudTrail Lake queries from natural language prompts \n in the CloudTrail user guide.

\n \n

Do not include any personally identifying, confidential, or sensitive information\n in your prompts.

\n

This feature uses generative AI large language models (LLMs); we recommend double-checking the\n LLM response.

\n
", "smithy.api#idempotent": {} } }, @@ -4689,7 +4701,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns information about a specific channel.\n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns information about a specific channel.\n

", "smithy.api#idempotent": {} } }, @@ -4769,7 +4781,7 @@ } ], "traits": { - "smithy.api#documentation": "

\nReturns the specified dashboard.\n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\nReturns the specified dashboard.\n

", "smithy.api#idempotent": {} } }, @@ -4994,7 +5006,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns information about an event data store specified as either an ARN or the ID\n portion of the ARN.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns information about an event data store specified as either an ARN or the ID\n portion of the ARN.

", "smithy.api#idempotent": {} } }, @@ -5208,7 +5220,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns information about a specific import.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns information about a specific import.

" } }, "com.amazonaws.cloudtrail#GetImportRequest": { @@ -5429,7 +5441,7 @@ } ], "traits": { - "smithy.api#documentation": "

Gets event data results of a query. You must specify the QueryID value\n returned by the StartQuery operation.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Gets event data results of a query. You must specify the QueryID value\n returned by the StartQuery operation.

", "smithy.api#paginated": { "inputToken": "NextToken", "outputToken": "NextToken" @@ -6929,7 +6941,7 @@ } ], "traits": { - "smithy.api#documentation": "

Lists the channels in the current account, and their source names. \n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Lists the channels in the current account, and their source names. \n

", "smithy.api#idempotent": {}, "smithy.api#paginated": { "inputToken": "NextToken", @@ -7001,7 +7013,7 @@ } ], "traits": { - "smithy.api#documentation": "

\n Returns information about all dashboards in the account, in the current Region.\n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\n Returns information about all dashboards in the account, in the current Region.\n

", "smithy.api#idempotent": {} } }, @@ -7092,7 +7104,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns information about all event data stores in the account, in the current\n Region.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns information about all event data stores in the account, in the current\n Region.

", "smithy.api#idempotent": {}, "smithy.api#paginated": { "inputToken": "NextToken", @@ -7173,7 +7185,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns a list of failures for the specified import.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns a list of failures for the specified import.

", "smithy.api#idempotent": {}, "smithy.api#paginated": { "inputToken": "NextToken", @@ -7265,7 +7277,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns information on all imports, or a select set of imports by\n ImportStatus or Destination.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns information on all imports, or a select set of imports by\n ImportStatus or Destination.

", "smithy.api#idempotent": {}, "smithy.api#paginated": { "inputToken": "NextToken", @@ -7356,7 +7368,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns Insights events generated on a trail that logs data events. You can list Insights events that occurred in a Region within the last 90 days.

\n

ListInsightsData supports the following Dimensions for Insights events:

\n \n

All dimensions are optional. The default number of results returned is 50, with a\n maximum of 50 possible. The response includes a token that you can use to get the next page\n of results.

\n

The rate of ListInsightsData requests is limited to two per second, per account, per Region. If\n this limit is exceeded, a throttling error occurs.

", + "smithy.api#documentation": "

Returns Insights events generated on a trail that logs data events. You can list Insights events that occurred in a Region within the last 90 days.

\n

ListInsightsData supports the following Dimensions for Insights events:

\n \n

All dimensions are optional. The default number of results returned is 50, with a\n maximum of 50 possible. The response includes a token that you can use to get the next page\n of results.

\n

The rate of ListInsightsData requests is limited to two per second, per account, per Region. If\n this limit is exceeded, a throttling error occurs.

\n \n

For data event Insights on organization trails, only the management account and delegated\n administrator accounts can call ListInsightsData. For these callers, the API returns\n Insights events only for the caller's own account. Member accounts cannot call this API on\n organization trails.

\n
", "smithy.api#idempotent": {}, "smithy.api#paginated": { "inputToken": "NextToken", @@ -7528,7 +7540,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns Insights metrics data for trails that have enabled Insights. The request must include the EventSource, \n EventName, and InsightType parameters.

\n

If the InsightType is set to ApiErrorRateInsight, the request must also include the ErrorCode parameter.

\n

The following are the available time periods for ListInsightsMetricData. Each cutoff is inclusive.

\n \n

To use ListInsightsMetricData operation, you must have the following permissions:

\n ", + "smithy.api#documentation": "

Returns Insights metrics data for trails that have enabled Insights. The request must include the EventSource, \n EventName, and InsightType parameters.

\n

If the InsightType is set to ApiErrorRateInsight, the request must also include the ErrorCode parameter.

\n

The following are the available time periods for ListInsightsMetricData. Each cutoff is inclusive.

\n \n

To use ListInsightsMetricData operation, you must have the following permissions:

\n \n \n

For data event Insights on organization trails, only the management account and delegated\n administrator accounts can call ListInsightsMetricData. For these callers, the API returns\n Insights metrics only for the caller's own account. Member accounts cannot call this API on\n organization trails.

\n
", "smithy.api#idempotent": {}, "smithy.api#paginated": { "inputToken": "NextToken", @@ -7794,7 +7806,7 @@ } ], "traits": { - "smithy.api#documentation": "

Returns a list of queries and query statuses for the past seven days. You must specify\n an ARN value for EventDataStore. Optionally, to shorten the list of results,\n you can specify a time range, formatted as timestamps, by adding StartTime and\n EndTime parameters, and a QueryStatus value. Valid values for\n QueryStatus include QUEUED, RUNNING,\n FINISHED, FAILED, TIMED_OUT, or\n CANCELLED.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Returns a list of queries and query statuses for the past seven days. You must specify\n an ARN value for EventDataStore. Optionally, to shorten the list of results,\n you can specify a time range, formatted as timestamps, by adding StartTime and\n EndTime parameters, and a QueryStatus value. Valid values for\n QueryStatus include QUEUED, RUNNING,\n FINISHED, FAILED, TIMED_OUT, or\n CANCELLED.

", "smithy.api#idempotent": {}, "smithy.api#paginated": { "inputToken": "NextToken", @@ -8863,6 +8875,9 @@ { "target": "com.amazonaws.cloudtrail#CloudTrailARNInvalidException" }, + { + "target": "com.amazonaws.cloudtrail#ConflictException" + }, { "target": "com.amazonaws.cloudtrail#InsufficientEncryptionPolicyException" }, @@ -9870,7 +9885,7 @@ } ], "traits": { - "smithy.api#documentation": "

Restores a deleted event data store specified by EventDataStore, which\n accepts an event data store ARN. You can only restore a deleted event data store within the\n seven-day wait period after deletion. Restoring an event data store can take several\n minutes, depending on the size of the event data store.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Restores a deleted event data store specified by EventDataStore, which\n accepts an event data store ARN. You can only restore a deleted event data store within the\n seven-day wait period after deletion. Restoring an event data store can take several\n minutes, depending on the size of the event data store.

" } }, "com.amazonaws.cloudtrail#RestoreEventDataStoreRequest": { @@ -10061,7 +10076,7 @@ } ], "traits": { - "smithy.api#documentation": "

\n Searches sample queries and returns a list of sample queries that are sorted by relevance. \n To search for sample queries, provide a natural language SearchPhrase in English.\n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\n Searches sample queries and returns a list of sample queries that are sorted by relevance. \n To search for sample queries, provide a natural language SearchPhrase in English.\n

", "smithy.api#idempotent": {} } }, @@ -10289,7 +10304,7 @@ } ], "traits": { - "smithy.api#documentation": "

\nStarts a refresh of the specified dashboard.\n

\n

\n Each time a dashboard is refreshed, CloudTrail runs queries to populate the dashboard's widgets. CloudTrail must be granted permissions to run the StartQuery operation on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to each event data store. For more information, \n see Example: Allow CloudTrail to run queries to populate a dashboard in the CloudTrail User Guide.\n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\nStarts a refresh of the specified dashboard.\n

\n

\n Each time a dashboard is refreshed, CloudTrail runs queries to populate the dashboard's widgets. CloudTrail must be granted permissions to run the StartQuery operation on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to each event data store. For more information, \n see Example: Allow CloudTrail to run queries to populate a dashboard in the CloudTrail User Guide.\n

", "smithy.api#idempotent": {} } }, @@ -10372,7 +10387,7 @@ } ], "traits": { - "smithy.api#documentation": "

Starts the ingestion of live events on an event data store specified as either an ARN or the ID portion of the ARN. To start ingestion, the event data store Status must be STOPPED_INGESTION \n and the eventCategory must be Management, Data, NetworkActivity, or ConfigurationItem.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Starts the ingestion of live events on an event data store specified as either an ARN or the ID portion of the ARN. To start ingestion, the event data store Status must be STOPPED_INGESTION \n and the eventCategory must be Management, Data, NetworkActivity, or ConfigurationItem.

" } }, "com.amazonaws.cloudtrail#StartEventDataStoreIngestionRequest": { @@ -10444,7 +10459,7 @@ } ], "traits": { - "smithy.api#documentation": "

Starts an import of logged trail events from a source S3 bucket to a destination event\n data store. By default, CloudTrail only imports events contained in the S3 bucket's\n CloudTrail prefix and the prefixes inside the CloudTrail prefix, and does not check prefixes for other Amazon Web Services\n services. If you want to import CloudTrail events contained in another prefix, you\n must include the prefix in the S3LocationUri. For more considerations about\n importing trail events, see Considerations for copying trail events in the CloudTrail User Guide.

\n

When you start a new import, the Destinations and\n ImportSource parameters are required. Before starting a new import, disable\n any access control lists (ACLs) attached to the source S3 bucket. For more information\n about disabling ACLs, see Controlling ownership of\n objects and disabling ACLs for your bucket.

\n

When you retry an import, the ImportID parameter is required.

\n \n

If the destination event data store is for an organization, you must use the\n management account to import trail events. You cannot use the delegated administrator\n account for the organization.

\n
" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Starts an import of logged trail events from a source S3 bucket to a destination event\n data store. By default, CloudTrail only imports events contained in the S3 bucket's\n CloudTrail prefix and the prefixes inside the CloudTrail prefix, and does not check prefixes for other Amazon Web Services\n services. If you want to import CloudTrail events contained in another prefix, you\n must include the prefix in the S3LocationUri. For more considerations about\n importing trail events, see Considerations for copying trail events in the CloudTrail User Guide.

\n

When you start a new import, the Destinations and\n ImportSource parameters are required. Before starting a new import, disable\n any access control lists (ACLs) attached to the source S3 bucket. For more information\n about disabling ACLs, see Controlling ownership of\n objects and disabling ACLs for your bucket.

\n

When you retry an import, the ImportID parameter is required.

\n \n

If the destination event data store is for an organization, you must use the\n management account to import trail events. You cannot use the delegated administrator\n account for the organization.

\n
" } }, "com.amazonaws.cloudtrail#StartImportRequest": { @@ -10666,7 +10681,7 @@ } ], "traits": { - "smithy.api#documentation": "

Starts a CloudTrail Lake query. Use the QueryStatement\n parameter to provide your SQL query, enclosed in single quotation marks. Use the optional\n DeliveryS3Uri parameter to deliver the query results to an S3\n bucket.

\n

\n StartQuery requires you specify either the QueryStatement parameter, or a QueryAlias and any QueryParameters. In the current release, \n the QueryAlias and QueryParameters parameters are used only for the queries that populate the CloudTrail Lake dashboards.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Starts a CloudTrail Lake query. Use the QueryStatement\n parameter to provide your SQL query, enclosed in single quotation marks. Use the optional\n DeliveryS3Uri parameter to deliver the query results to an S3\n bucket.

\n

\n StartQuery requires you specify either the QueryStatement parameter, or a QueryAlias and any QueryParameters. In the current release, \n the QueryAlias and QueryParameters parameters are used only for the queries that populate the CloudTrail Lake dashboards.

", "smithy.api#idempotent": {} } }, @@ -10772,7 +10787,7 @@ } ], "traits": { - "smithy.api#documentation": "

Stops the ingestion of live events on an event data store specified as either an ARN or the ID portion of the ARN. To stop ingestion, the event data store Status must be ENABLED \n and the eventCategory must be Management, Data, NetworkActivity, or ConfigurationItem.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Stops the ingestion of live events on an event data store specified as either an ARN or the ID portion of the ARN. To stop ingestion, the event data store Status must be ENABLED \n and the eventCategory must be Management, Data, NetworkActivity, or ConfigurationItem.

" } }, "com.amazonaws.cloudtrail#StopEventDataStoreIngestionRequest": { @@ -10820,7 +10835,7 @@ } ], "traits": { - "smithy.api#documentation": "

Stops a specified import.

" + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Stops a specified import.

" } }, "com.amazonaws.cloudtrail#StopImportRequest": { @@ -11157,7 +11172,7 @@ "IncludeGlobalServiceEvents": { "target": "com.amazonaws.cloudtrail#Boolean", "traits": { - "smithy.api#documentation": "

Set to True to include Amazon Web Services API calls\n from Amazon Web Services global services such as IAM. Otherwise, False.

" + "smithy.api#documentation": "

Set to True to include Amazon Web Services API calls\n from Amazon Web Services global services such as IAM. Otherwise, False. Setting this value to true only delivers\n global service events to the trail if the trail is multi-Region or if the trail's home\n Region is the partition leader Region (for example, us-east-1).

" } }, "IsMultiRegionTrail": { @@ -11219,6 +11234,12 @@ "traits": { "smithy.api#documentation": "

Specifies whether the trail is an organization trail.

" } + }, + "RecursiveLogging": { + "target": "com.amazonaws.cloudtrail#Boolean", + "traits": { + "smithy.api#documentation": "

Specifies whether recursive logging is enabled for the trail. If you set\n RecursiveLogging to false, CloudTrail suppresses\n events generated by CloudTrail when it delivers log files to your trail's\n destinations, including Amazon S3 and CloudWatch Logs. The default value is\n true.

" + } } }, "traits": { @@ -11417,7 +11438,7 @@ } ], "traits": { - "smithy.api#documentation": "

Updates a channel specified by a required channel ARN or UUID.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Updates a channel specified by a required channel ARN or UUID.

", "smithy.api#idempotent": {} } }, @@ -11515,7 +11536,7 @@ } ], "traits": { - "smithy.api#documentation": "

\nUpdates the specified dashboard.\n

\n

\n To set a refresh schedule, CloudTrail must be granted permissions to run the StartDashboardRefresh operation to refresh the dashboard on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to the dashboard. For more information, \n see \n Resource-based policy example for a dashboard in the CloudTrail User Guide.\n

\n

\n CloudTrail runs queries to populate the dashboard's widgets during a manual or scheduled refresh. CloudTrail must be granted permissions to run the StartQuery operation on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to each event data store. For more information, \n see Example: Allow CloudTrail to run queries to populate a dashboard in the CloudTrail User Guide.\n

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

\nUpdates the specified dashboard.\n

\n

\n To set a refresh schedule, CloudTrail must be granted permissions to run the StartDashboardRefresh operation to refresh the dashboard on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to the dashboard. For more information, \n see \n Resource-based policy example for a dashboard in the CloudTrail User Guide.\n

\n

\n CloudTrail runs queries to populate the dashboard's widgets during a manual or scheduled refresh. CloudTrail must be granted permissions to run the StartQuery operation on your behalf. To provide permissions, run the PutResourcePolicy operation to attach a resource-based policy to each event data store. For more information, \n see Example: Allow CloudTrail to run queries to populate a dashboard in the CloudTrail User Guide.\n

", "smithy.api#idempotent": {} } }, @@ -11685,7 +11706,7 @@ } ], "traits": { - "smithy.api#documentation": "

Updates an event data store. The required EventDataStore value is an ARN or\n the ID portion of the ARN. Other parameters are optional, but at least one optional\n parameter must be specified, or CloudTrail throws an error.\n RetentionPeriod is in days, and valid values are integers between 7 and\n 3653 if the BillingMode is set to EXTENDABLE_RETENTION_PRICING, or between 7 and 2557 if BillingMode is set to FIXED_RETENTION_PRICING. By default, TerminationProtection is enabled.

\n

For event data stores for CloudTrail events, AdvancedEventSelectors\n includes or excludes management, data, or network activity events in your event data store. For more\n information about AdvancedEventSelectors, see AdvancedEventSelectors.

\n

For event data stores for CloudTrail Insights events, Config configuration items, Audit Manager evidence, or non-Amazon Web Services events,\n AdvancedEventSelectors includes events of that type in your event data store.

", + "smithy.api#documentation": "\n

CloudTrail Lake will no longer be open to new customers starting May 31, 2026. If you would like to use CloudTrail Lake, sign up prior to that date. Existing customers can continue to use the service as normal. For more information, see CloudTrail Lake availability change.

\n
\n

Updates an event data store. The required EventDataStore value is an ARN or\n the ID portion of the ARN. Other parameters are optional, but at least one optional\n parameter must be specified, or CloudTrail throws an error.\n RetentionPeriod is in days, and valid values are integers between 7 and\n 3653 if the BillingMode is set to EXTENDABLE_RETENTION_PRICING, or between 7 and 2557 if BillingMode is set to FIXED_RETENTION_PRICING. By default, TerminationProtection is enabled.

\n

For event data stores for CloudTrail events, AdvancedEventSelectors\n includes or excludes management, data, or network activity events in your event data store. For more\n information about AdvancedEventSelectors, see AdvancedEventSelectors.

\n

For event data stores for CloudTrail Insights events, Config configuration items, Audit Manager evidence, or non-Amazon Web Services events,\n AdvancedEventSelectors includes events of that type in your event data store.

", "smithy.api#idempotent": {} } }, @@ -11989,7 +12010,7 @@ "IncludeGlobalServiceEvents": { "target": "com.amazonaws.cloudtrail#Boolean", "traits": { - "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the log files.

" + "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the log files. Setting this value to true only delivers\n global service events to the trail if the trail is multi-Region or if the trail's home\n Region is the partition leader Region (for example, us-east-1).

" } }, "IsMultiRegionTrail": { @@ -12027,6 +12048,12 @@ "traits": { "smithy.api#documentation": "

Specifies whether the trail is applied to all accounts in an organization in Organizations, or only for the current Amazon Web Services account. The default is false,\n and cannot be true unless the call is made on behalf of an Amazon Web Services account that\n is the management account for an organization in Organizations. If the trail is not an organization trail and this is set to\n true, the trail will be created in all Amazon Web Services accounts that\n belong to the organization. If the trail is an organization trail and this is set to\n false, the trail will remain in the current Amazon Web Services account but\n be deleted from all member accounts in the organization.

\n \n

Only the management account for the organization can convert an organization trail to a non-organization trail, or convert a non-organization trail to \n an organization trail.

\n
" } + }, + "RecursiveLogging": { + "target": "com.amazonaws.cloudtrail#Boolean", + "traits": { + "smithy.api#documentation": "

Specifies whether recursive logging is enabled for the trail. If you set\n RecursiveLogging to false, CloudTrail suppresses\n events generated by CloudTrail when it delivers log files to your trail's\n destinations, including Amazon S3 and CloudWatch Logs. The default value is\n true.

" + } } }, "traits": { @@ -12071,7 +12098,7 @@ "IncludeGlobalServiceEvents": { "target": "com.amazonaws.cloudtrail#Boolean", "traits": { - "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the log files.

" + "smithy.api#documentation": "

Specifies whether the trail is publishing events from global services such as IAM to the log files. Setting this value to true only delivers\n global service events to the trail if the trail is multi-Region or if the trail's home\n Region is the partition leader Region (for example, us-east-1).

" } }, "IsMultiRegionTrail": { @@ -12115,6 +12142,12 @@ "traits": { "smithy.api#documentation": "

Specifies whether the trail is an organization trail.

" } + }, + "RecursiveLogging": { + "target": "com.amazonaws.cloudtrail#Boolean", + "traits": { + "smithy.api#documentation": "

Specifies whether recursive logging is enabled for the trail.

" + } } }, "traits": { diff --git a/aws-models/ec2.json b/aws-models/ec2.json index d03d4cf5e..5a9e04738 100644 --- a/aws-models/ec2.json +++ b/aws-models/ec2.json @@ -11842,6 +11842,17 @@ "com.amazonaws.ec2#Boolean": { "type": "boolean" }, + "com.amazonaws.ec2#BootModeOverrideValues": { + "type": "enum", + "members": { + "uefi": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "uefi" + } + } + } + }, "com.amazonaws.ec2#BootModeType": { "type": "enum", "members": { @@ -18636,6 +18647,18 @@ "smithy.api#documentation": "

Unique, case-sensitive identifier that you provide to ensure the idempotency of the \n request. For more information, see \n Ensure Idempotency.

", "smithy.api#idempotencyToken": {} } + }, + "Encrypted": { + "target": "com.amazonaws.ec2#Boolean", + "traits": { + "smithy.api#documentation": "

Indicates whether to encrypt the volume copy. If the source volume is encrypted, the \n service always encrypts the copy regardless of this value. Set to true to \n encrypt a copy of an unencrypted source volume during the copy operation. If you set \n Encrypted to true but do not specify KmsKeyId, the \n service uses the default KMS key for EBS encryption in your account.

" + } + }, + "KmsKeyId": { + "target": "com.amazonaws.ec2#KmsKeyId", + "traits": { + "smithy.api#documentation": "

The identifier of the KMS key to use for encryption of the volume copy. Specify a \n symmetric encryption KMS key. You can specify a KMS key using the key ID, key ARN, alias \n name, or alias ARN. If you set Encrypted to true but do not \n specify this parameter, the service uses the default KMS key for EBS encryption in your \n account. For cross-account volume copies, this must be a KMS key in the calling \n account.

" + } } }, "traits": { @@ -21014,6 +21037,12 @@ "smithy.api#documentation": "\n

Only supported for instances in Local Zones and for instances on Outposts that support\n local snapshots. If the source instance is not in one of these locations, omit this\n parameter.

\n
\n

The Amazon S3 location where the snapshots will be stored.

\n \n

If the source instance is in a Local Zone and you omit this parameter, regional snapshots\n are created in the parent Region of the Local Zone.

\n

If the source instance is on an Outpost that supports local snapshots, this parameter is\n required. If you omit it, the request fails with an\n InvalidParameterValue error.

\n

Default: regional (for instances in Local Zones only)

" } }, + "BootModeOverride": { + "target": "com.amazonaws.ec2#BootModeOverrideValues", + "traits": { + "smithy.api#documentation": "

The boot mode of the new image, which overrides the default boot mode. By default, \n if you do not specify this parameter, the new image inherits \n the boot-mode from the source instance.

\n

A value of uefi indicates that the image only supports UEFI boot mode. You can\n specify this parameter only if the current-instance-boot-mode of the source instance is\n uefi. To find the boot-mode or current-instance-boot-mode of \n an instance, see DescribeInstances.

\n \n

The operating system contained in the AMI must be configured to support the specified\n boot mode.

\n
\n

For more information, see Instance launch behavior with Amazon EC2 boot modes in\n the Amazon EC2 User Guide.

" + } + }, "DryRun": { "target": "com.amazonaws.ec2#Boolean", "traits": { @@ -42548,7 +42577,7 @@ "target": "com.amazonaws.ec2#DescribeInstanceCreditSpecificationsResult" }, "traits": { - "smithy.api#documentation": "

Describes the credit option for CPU usage of the specified burstable performance\n instances. The credit options are standard and\n unlimited.

\n

If you do not specify an instance ID, Amazon EC2 returns burstable performance\n instances with the unlimited credit option, as well as instances that were\n previously configured as T2, T3, and T3a with the unlimited credit option.\n For example, if you resize a T2 instance, while it is configured as\n unlimited, to an M4 instance, Amazon EC2 returns the M4\n instance.

\n

If you specify one or more instance IDs, Amazon EC2 returns the credit option\n (standard or unlimited) of those instances. If you specify\n an instance ID that is not valid, such as an instance that is not a burstable\n performance instance, an error is returned.

\n

Recently terminated instances might appear in the returned results. This interval is\n usually less than one hour.

\n

If an Availability Zone is experiencing a service disruption and you specify instance\n IDs in the affected zone, or do not specify any instance IDs at all, the call fails. If\n you specify only instance IDs in an unaffected zone, the call works normally.

\n

For more information, see Burstable\n performance instances in the Amazon EC2 User Guide.

", + "smithy.api#documentation": "

Describes the credit option for CPU usage of the specified burstable performance\n instances. The credit options are standard and\n unlimited.

\n

If you do not specify an instance ID, Amazon EC2 returns burstable performance\n instances with the unlimited credit option, as well as instances that were\n previously configured as T2, T3, and T3a with the unlimited credit option.\n For example, if you resize a T2 instance, while it is configured as\n unlimited, to an M4 instance, Amazon EC2 returns the M4\n instance.

\n

If you specify one or more instance IDs, Amazon EC2 returns the credit option\n (standard or unlimited) of those instances. If you specify\n an instance ID that is not a burstable performance instance, Amazon EC2 returns the\n standard credit option.

\n

Recently terminated instances might appear in the returned results. This interval is\n usually less than one hour.

\n

If an Availability Zone is experiencing a service disruption and you specify instance\n IDs in the affected zone, or do not specify any instance IDs at all, the call fails. If\n you specify only instance IDs in an unaffected zone, the call works normally.

\n

For more information, see Burstable\n performance instances in the Amazon EC2 User Guide.

", "smithy.api#paginated": { "inputToken": "NextToken", "outputToken": "NextToken", @@ -110794,6 +110823,14 @@ "smithy.api#documentation": "

The maximum number of the ENA queues for each interface.

", "smithy.api#xmlName": "maximumEnaQueueCountPerInterface" } + }, + "InterfaceTypes": { + "target": "com.amazonaws.ec2#NetworkCardInterfaceTypeList", + "traits": { + "aws.protocols#ec2QueryName": "InterfaceTypeSet", + "smithy.api#documentation": "

The supported interface types for the network card.

", + "smithy.api#xmlName": "interfaceTypeSet" + } } }, "traits": { @@ -110809,6 +110846,44 @@ } } }, + "com.amazonaws.ec2#NetworkCardInterfaceType": { + "type": "enum", + "members": { + "interface": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "interface" + } + }, + "efa": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "efa" + } + }, + "efa_only": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "efa-only" + } + }, + "secondary": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "secondary" + } + } + } + }, + "com.amazonaws.ec2#NetworkCardInterfaceTypeList": { + "type": "list", + "member": { + "target": "com.amazonaws.ec2#NetworkCardInterfaceType", + "traits": { + "smithy.api#xmlName": "item" + } + } + }, "com.amazonaws.ec2#NetworkInfo": { "type": "structure", "members": { @@ -141735,6 +141810,22 @@ "smithy.api#xmlName": "volumeInitializationRate" } }, + "VolumeArn": { + "target": "com.amazonaws.ec2#String", + "traits": { + "aws.protocols#ec2QueryName": "VolumeArn", + "smithy.api#documentation": "

The Amazon Resource Name (ARN) of the volume.

", + "smithy.api#xmlName": "volumeArn" + } + }, + "OwnerId": { + "target": "com.amazonaws.ec2#String", + "traits": { + "aws.protocols#ec2QueryName": "OwnerId", + "smithy.api#documentation": "

The ID of the Amazon Web Services account that owns the volume.

", + "smithy.api#xmlName": "ownerId" + } + }, "VolumeId": { "target": "com.amazonaws.ec2#String", "traits": { diff --git a/aws-models/ecs.json b/aws-models/ecs.json index 40f612c8a..24f6ff836 100644 --- a/aws-models/ecs.json +++ b/aws-models/ecs.json @@ -4665,6 +4665,12 @@ "smithy.api#documentation": "

The amount of memory (in MiB) used by the task. This parameter determines the memory allocation for each task in the Express service. The default value for an express service is 512 MiB.

" } }, + "cpuArchitecture": { + "target": "com.amazonaws.ecs#ExpressCpuArchitecture", + "traits": { + "smithy.api#documentation": "

The CPU architecture that the tasks in the Express service run on. Amazon ECS applies this value to the task definition revision that it registers for the service. If you don't specify a value, the default is X86_64.

Valid values:

Make sure that the container image that you specify supports the architecture that you choose. The operating system family for an Express service is always LINUX.

You can't specify cpuArchitecture when you also specify taskDefinitionArn, because this value applies only to a task definition that Amazon ECS registers on your behalf.

" + } + }, "scalingTarget": { "target": "com.amazonaws.ecs#ExpressGatewayScalingTarget", "traits": { @@ -4680,7 +4686,7 @@ "taskDefinitionArn": { "target": "com.amazonaws.ecs#String", "traits": { - "smithy.api#documentation": "

The Amazon Resource Name (ARN) of a task definition to use to create the Express Gateway service. This allows you to manage your own task definition, giving you more control over the service configuration such as adding sidecar containers.

The task definition must have a container named Main with a single TCP port mapping that includes a container port and port name. The task definition must also have FARGATE compatibility.

If you provide a task definition ARN, you cannot also specify primaryContainer, executionRoleArn, taskRoleArn, cpu, or memory.

" + "smithy.api#documentation": "

The Amazon Resource Name (ARN) of a task definition to use to create the Express Gateway service. This allows you to manage your own task definition, giving you more control over the service configuration such as adding sidecar containers.

The task definition must have a container named Main with a single TCP port mapping that includes a container port and port name. The task definition must also have FARGATE compatibility.

If you provide a task definition ARN, you cannot also specify primaryContainer, executionRoleArn, taskRoleArn, cpu, memory, or cpuArchitecture.

" } } }, @@ -12040,6 +12046,23 @@ "smithy.api#output": {} } }, + "com.amazonaws.ecs#ExpressCpuArchitecture": { + "type": "enum", + "members": { + "X86_64": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "X86_64" + } + }, + "ARM64": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "ARM64" + } + } + } + }, "com.amazonaws.ecs#ExpressGatewayContainer": { "type": "structure", "members": { @@ -12198,6 +12221,12 @@ "smithy.api#documentation": "

The memory allocation for tasks in this service revision.

" } }, + "cpuArchitecture": { + "target": "com.amazonaws.ecs#ExpressCpuArchitecture", + "traits": { + "smithy.api#documentation": "

The CPU architecture that the tasks in this service revision run on. This is the architecture from the task definition that the service revision uses, so it reflects the default or the previously configured architecture when the request that created the revision didn't specify one.

Valid values:

This value isn't returned when the task definition for the service revision doesn't specify a runtime platform. Because the architecture comes from each service revision's own task definition, revisions of the same service can report different architectures.

" + } + }, "networkConfiguration": { "target": "com.amazonaws.ecs#ExpressGatewayServiceNetworkConfiguration", "traits": { @@ -24528,6 +24557,12 @@ "smithy.api#documentation": "

The amount of memory (in MiB) used by the task.

" } }, + "cpuArchitecture": { + "target": "com.amazonaws.ecs#ExpressCpuArchitecture", + "traits": { + "smithy.api#documentation": "

The CPU architecture that the tasks in the Express service run on. Amazon ECS applies this value to the task definition revision that it registers for the service. If you don't specify a value, the service keeps the architecture that it currently runs on.

Valid values:

Changing the architecture starts a new deployment that replaces the running tasks. Make sure that the container image that the service uses supports the architecture that you choose. The operating system family for an Express service is always LINUX.

You can't specify cpuArchitecture when you also specify taskDefinitionArn, because this value applies only to a task definition that Amazon ECS registers on your behalf.

" + } + }, "scalingTarget": { "target": "com.amazonaws.ecs#ExpressGatewayScalingTarget", "traits": { @@ -24537,7 +24572,7 @@ "taskDefinitionArn": { "target": "com.amazonaws.ecs#String", "traits": { - "smithy.api#documentation": "

The Amazon Resource Name (ARN) of a task definition to use to update the Express Gateway service. This allows you to manage your own task definition, giving you more control over the service configuration such as adding sidecar containers.

The task definition must have a container named Main with a single TCP port mapping that includes a container port and port name. The task definition must also have FARGATE compatibility.

If you provide a task definition ARN, you cannot also specify primaryContainer, executionRoleArn, taskRoleArn, cpu, or memory.

" + "smithy.api#documentation": "

The Amazon Resource Name (ARN) of a task definition to use to update the Express Gateway service. This allows you to manage your own task definition, giving you more control over the service configuration such as adding sidecar containers.

The task definition must have a container named Main with a single TCP port mapping that includes a container port and port name. The task definition must also have FARGATE compatibility.

If you provide a task definition ARN, you cannot also specify primaryContainer, executionRoleArn, taskRoleArn, cpu, memory, or cpuArchitecture.

" } } }, diff --git a/aws-models/lambda.json b/aws-models/lambda.json index 5d3c9b6fb..4dafc1823 100644 --- a/aws-models/lambda.json +++ b/aws-models/lambda.json @@ -5383,7 +5383,7 @@ "Timeout": { "target": "com.amazonaws.lambda#Timeout", "traits": { - "smithy.api#documentation": "

The amount of time (in seconds) that Lambda allows a function to run before stopping it. The default is 3 seconds. The maximum allowed value is 900 seconds. For more information, see Lambda execution environment.

", + "smithy.api#documentation": "

The amount of time (in seconds) that Lambda allows a function to run before stopping it. The default is 3 seconds, and the maximum allowed value is 900 seconds. For functions using Lambda Managed Instances, asynchronous invocations and event source mapping invocations (except Amazon MQ and Amazon DocumentDB) support a maximum allowed value of 5,400 seconds (90 minutes). For more information, see Lambda execution environment.

", "smithy.api#tags": [ "feature:public" ] @@ -13396,7 +13396,7 @@ "smithy.api#documentation": "

Retrieves the provisioned concurrency configuration for a function's alias or version.

", "smithy.api#examples": [ { - "documentation": "The following example displays details for the provisioned concurrency configuration for the BLUE alias of the specified function.", + "documentation": "The following example returns details for the provisioned concurrency configuration for the BLUE alias of the specified function.", "input": { "FunctionName": "my-function", "Qualifier": "BLUE" @@ -13408,10 +13408,10 @@ "RequestedProvisionedConcurrentExecutions": 100, "Status": "READY" }, - "title": "To view a provisioned concurrency configuration" + "title": "To get a provisioned concurrency configuration" }, { - "documentation": "The following example returns details for the provisioned concurrency configuration for the BLUE alias of the specified function.", + "documentation": "The following example displays details for the provisioned concurrency configuration for the BLUE alias of the specified function.", "input": { "FunctionName": "my-function", "Qualifier": "BLUE" @@ -13423,7 +13423,7 @@ "RequestedProvisionedConcurrentExecutions": 100, "Status": "READY" }, - "title": "To get a provisioned concurrency configuration" + "title": "To view a provisioned concurrency configuration" } ], "smithy.api#http": { @@ -26732,7 +26732,7 @@ "Timeout": { "target": "com.amazonaws.lambda#Timeout", "traits": { - "smithy.api#documentation": "

The amount of time (in seconds) that Lambda allows a function to run before stopping it. The default is 3 seconds. The maximum allowed value is 900 seconds. For more information, see Lambda execution environment.

", + "smithy.api#documentation": "

The amount of time (in seconds) that Lambda allows a function to run before stopping it. The default is 3 seconds, and the maximum allowed value is 900 seconds. For functions using Lambda Managed Instances, asynchronous invocations and event source mapping invocations (except Amazon MQ and Amazon DocumentDB) support a maximum allowed value of 5,400 seconds (90 minutes). For more information, see Lambda execution environment.

", "smithy.api#tags": [ "feature:public" ] diff --git a/aws-models/mediaconvert.json b/aws-models/mediaconvert.json index a01d8ce33..e755597f6 100644 --- a/aws-models/mediaconvert.json +++ b/aws-models/mediaconvert.json @@ -1272,7 +1272,7 @@ } }, "traits": { - "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9." + "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9. A video track can declare an aspect ratio in two independent places, and MediaConvert reports each one where it was found rather than choosing between them. The ratio declared by the container appears on the video track itself, and the ratio declared by the video essence appears under codecMetadata. When a file declares an aspect ratio in only one of the two places, the other is null; when it declares both and they disagree, you can compare them and decide which to use." } }, "com.amazonaws.mediaconvert#AssociateCertificate": { @@ -5745,6 +5745,20 @@ "smithy.api#jsonName": "contentLightLevel" } }, + "DisplayAspectRatio": { + "target": "com.amazonaws.mediaconvert#AspectRatio", + "traits": { + "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9. A video track can declare an aspect ratio in two independent places, and MediaConvert reports each one where it was found rather than choosing between them. The ratio declared by the container appears on the video track itself, and the ratio declared by the video essence appears under codecMetadata. When a file declares an aspect ratio in only one of the two places, the other is null; when it declares both and they disagree, you can compare them and decide which to use.", + "smithy.api#jsonName": "displayAspectRatio" + } + }, + "DolbyVision": { + "target": "com.amazonaws.mediaconvert#DolbyVisionMetadata", + "traits": { + "smithy.api#documentation": "Dolby Vision characteristics of the video track: the profile and level, and whether the RPU (dynamic metadata), base layer, and enhancement layer are present. Use this to distinguish Dolby Vision content from standard HEVC and to choose your encoding or passthrough settings. Omitted when the content is not Dolby Vision.", + "smithy.api#jsonName": "dolbyVision" + } + }, "FieldOrder": { "target": "com.amazonaws.mediaconvert#__string", "traits": { @@ -5794,6 +5808,13 @@ "smithy.api#jsonName": "rotation" } }, + "SampleAspectRatio": { + "target": "com.amazonaws.mediaconvert#AspectRatio", + "traits": { + "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9. A video track can declare an aspect ratio in two independent places, and MediaConvert reports each one where it was found rather than choosing between them. The ratio declared by the container appears on the video track itself, and the ratio declared by the video essence appears under codecMetadata. When a file declares an aspect ratio in only one of the two places, the other is null; when it declares both and they disagree, you can compare them and decide which to use.", + "smithy.api#jsonName": "sampleAspectRatio" + } + }, "ScanType": { "target": "com.amazonaws.mediaconvert#__string", "traits": { @@ -6254,7 +6275,7 @@ "Format": { "target": "com.amazonaws.mediaconvert#Format", "traits": { - "smithy.api#documentation": "The format of your media file. For example: MP4, QuickTime (MOV), Matroska (MKV), WebM, MXF, Wave, AVI, MPEG-TS, MPEG-PS, MP3, FLAC, ASF (Windows Media / WMA), OGG. Note that this will be blank if your media file has a format that the MediaConvert Probe operation does not recognize.", + "smithy.api#documentation": "The format of your media file. For example: MP4, QuickTime (MOV), Matroska (MKV), WebM, MXF, Wave, AVI, MPEG-TS, MPEG-PS, MP3, FLAC, ASF (Windows Media / WMA), or OGG. Note that this will be blank if your media file has a format that the MediaConvert Probe operation does not recognize.", "smithy.api#jsonName": "format" } }, @@ -8437,6 +8458,69 @@ "smithy.api#documentation": "Required when you set Dolby Vision Profile to Profile 8.1. When you set Content mapping to None, content mapping is not applied to the HDR10-compatible signal. Depending on the source peak nit level, clipping might occur on HDR devices without Dolby Vision. When you set Content mapping to HDR10 1000, the transcoder creates a 1,000 nits peak HDR10-compatible signal by applying static content mapping to the source. This mode is speed-optimized for PQ10 sources with metadata that is created from analysis. For graded Dolby Vision content, be aware that creative intent might not be guaranteed with extreme 1,000 nits trims." } }, + "com.amazonaws.mediaconvert#DolbyVisionMetadata": { + "type": "structure", + "members": { + "BaseLayer": { + "target": "com.amazonaws.mediaconvert#DolbyVisionPresence", + "traits": { + "smithy.api#documentation": "Whether a Dolby Vision component is present in the track.", + "smithy.api#jsonName": "baseLayer" + } + }, + "EnhancementLayer": { + "target": "com.amazonaws.mediaconvert#DolbyVisionPresence", + "traits": { + "smithy.api#documentation": "Whether a Dolby Vision component is present in the track.", + "smithy.api#jsonName": "enhancementLayer" + } + }, + "Level": { + "target": "com.amazonaws.mediaconvert#__integer", + "traits": { + "smithy.api#documentation": "The Dolby Vision level, which indicates the maximum resolution and frame rate.", + "smithy.api#jsonName": "level" + } + }, + "Profile": { + "target": "com.amazonaws.mediaconvert#__integer", + "traits": { + "smithy.api#documentation": "The Dolby Vision profile, for example 5, 7, or 8. The profile determines the layer structure and playback compatibility of the content.", + "smithy.api#jsonName": "profile" + } + }, + "Rpu": { + "target": "com.amazonaws.mediaconvert#DolbyVisionPresence", + "traits": { + "smithy.api#documentation": "Whether a Dolby Vision component is present in the track.", + "smithy.api#jsonName": "rpu" + } + } + }, + "traits": { + "smithy.api#documentation": "Dolby Vision characteristics of the video track: the profile and level, and whether the RPU (dynamic metadata), base layer, and enhancement layer are present. Use this to distinguish Dolby Vision content from standard HEVC and to choose your encoding or passthrough settings. Omitted when the content is not Dolby Vision." + } + }, + "com.amazonaws.mediaconvert#DolbyVisionPresence": { + "type": "enum", + "members": { + "PRESENT": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "PRESENT" + } + }, + "ABSENT": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "ABSENT" + } + } + }, + "traits": { + "smithy.api#documentation": "Whether a Dolby Vision component is present in the track." + } + }, "com.amazonaws.mediaconvert#DolbyVisionProfile": { "type": "enum", "members": { @@ -24399,6 +24483,9 @@ }, { "target": "com.amazonaws.mediaconvert#TooManyRequestsException" + }, + { + "target": "com.amazonaws.mediaconvert#UnprocessableEntityException" } ], "traits": { @@ -27472,6 +27559,22 @@ "smithy.api#documentation": "When you do frame rate conversion from 23.976 frames per second (fps) to 29.97 fps, and your output scan type is interlaced, you can optionally enable hard telecine to create a smoother picture. When you keep the default value, None, MediaConvert does a standard frame rate conversion to 29.97 without doing anything with the field polarity to create a smoother picture." } }, + "com.amazonaws.mediaconvert#UnprocessableEntityException": { + "type": "structure", + "members": { + "Message": { + "target": "com.amazonaws.mediaconvert#__string", + "traits": { + "smithy.api#jsonName": "message" + } + } + }, + "traits": { + "smithy.api#documentation": "The input file was recognized but appears to be malformed or corrupt.", + "smithy.api#error": "client", + "smithy.api#httpError": 422 + } + }, "com.amazonaws.mediaconvert#UntagResource": { "type": "operation", "input": { @@ -28859,7 +28962,7 @@ "DisplayAspectRatio": { "target": "com.amazonaws.mediaconvert#AspectRatio", "traits": { - "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9.", + "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9. A video track can declare an aspect ratio in two independent places, and MediaConvert reports each one where it was found rather than choosing between them. The ratio declared by the container appears on the video track itself, and the ratio declared by the video essence appears under codecMetadata. When a file declares an aspect ratio in only one of the two places, the other is null; when it declares both and they disagree, you can compare them and decide which to use.", "smithy.api#jsonName": "displayAspectRatio" } }, @@ -28901,7 +29004,7 @@ "SampleAspectRatio": { "target": "com.amazonaws.mediaconvert#AspectRatio", "traits": { - "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9.", + "smithy.api#documentation": "An aspect ratio expressed as a fraction with numerator and denominator values, reduced to lowest terms. Used for the sample (pixel) aspect ratio and the display aspect ratio of a video track. For example, a 720x576 anamorphic track has a sample aspect ratio of 64 / 45 and a display aspect ratio of 16 / 9. A video track can declare an aspect ratio in two independent places, and MediaConvert reports each one where it was found rather than choosing between them. The ratio declared by the container appears on the video track itself, and the ratio declared by the video essence appears under codecMetadata. When a file declares an aspect ratio in only one of the two places, the other is null; when it declares both and they disagree, you can compare them and decide which to use.", "smithy.api#jsonName": "sampleAspectRatio" } }, diff --git a/aws-models/s3.json b/aws-models/s3.json index 3e948c9d5..0cd5a6853 100644 --- a/aws-models/s3.json +++ b/aws-models/s3.json @@ -29392,6 +29392,27 @@ "smithy.api#httpHeader": "x-amz-object-lock-legal-hold" } }, + "ObjectLockEventHold": { + "target": "com.amazonaws.s3#ObjectLockEventHold", + "traits": { + "smithy.api#documentation": "

The event hold status to apply to the object copy. Set to ON to enable or\n OFF to disable.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold" + } + }, + "ObjectLockEventHoldDurationDays": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationDays", + "traits": { + "smithy.api#documentation": "

The event hold duration in days to apply to the object copy. You cannot specify a duration\n in both days and years.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-days" + } + }, + "ObjectLockEventHoldDurationYears": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationYears", + "traits": { + "smithy.api#documentation": "

The event hold duration in years to apply to the object copy. You cannot specify a\n duration in both days and years.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-years" + } + }, "ExpectedBucketOwner": { "target": "com.amazonaws.s3#AccountId", "traits": { @@ -29435,7 +29456,7 @@ "ChecksumCRC32": { "target": "com.amazonaws.s3#ChecksumCRC32", "traits": { - "smithy.api#documentation": "

The Base64 encoded, 32-bit CRC32 checksum of the object. This checksum is only present if the object was uploaded\n with the object. For more information, see \n Checking object integrity in the Amazon S3 User Guide.

" + "smithy.api#documentation": "

The Base64 encoded, 32-bit CRC32 checksum of the object. This checksum is only present if the checksum was uploaded\n with the object. For more information, see \n Checking object integrity in the Amazon S3 User Guide.

" } }, "ChecksumCRC32C": { @@ -30306,6 +30327,27 @@ "smithy.api#httpHeader": "x-amz-object-lock-legal-hold" } }, + "ObjectLockEventHold": { + "target": "com.amazonaws.s3#ObjectLockEventHold", + "traits": { + "smithy.api#documentation": "

Specifies the event hold status to apply to the uploaded object. Set to ON to enable\n or OFF to disable.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold" + } + }, + "ObjectLockEventHoldDurationDays": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationDays", + "traits": { + "smithy.api#documentation": "

Specifies the event hold duration in days to apply to the uploaded object. You cannot\n specify a duration in both days and years.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-days" + } + }, + "ObjectLockEventHoldDurationYears": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationYears", + "traits": { + "smithy.api#documentation": "

Specifies the event hold duration in years to apply to the uploaded object. You cannot\n specify a duration in both days and years.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-years" + } + }, "ExpectedBucketOwner": { "target": "com.amazonaws.s3#AccountId", "traits": { @@ -30510,6 +30552,12 @@ "traits": { "smithy.api#documentation": "

The number of years that you want to specify for the default retention period. Must be used with\n Mode.

" } + }, + "DefaultEventHold": { + "target": "com.amazonaws.s3#EventHoldDuration", + "traits": { + "smithy.api#documentation": "

The default event hold duration to be applied to new objects placed in the specified bucket. When\n configured, new objects will automatically have an event hold enabled with this duration.

" + } } }, "traits": { @@ -32520,6 +32568,12 @@ "traits": { "smithy.api#enumValue": "s3:ObjectAnnotation:Delete" } + }, + "s3_ObjectRetention_Put": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "s3:ObjectRetention:Put" + } } }, "traits": { @@ -32533,6 +32587,26 @@ "smithy.api#documentation": "

A container for specifying the configuration for Amazon EventBridge.

" } }, + "com.amazonaws.s3#EventHoldDuration": { + "type": "structure", + "members": { + "Days": { + "target": "com.amazonaws.s3#Days", + "traits": { + "smithy.api#documentation": "

The number of days for the event hold duration. The minimum value is 1 and the maximum value is\n 36,500.

" + } + }, + "Years": { + "target": "com.amazonaws.s3#Years", + "traits": { + "smithy.api#documentation": "

The number of years for the event hold duration. The minimum value is 1 and the maximum value is\n 100.

" + } + } + }, + "traits": { + "smithy.api#documentation": "

Contains the event hold duration configuration, specified in either days or years.

" + } + }, "com.amazonaws.s3#EventList": { "type": "list", "member": { @@ -35335,7 +35409,7 @@ "ChecksumCRC32": { "target": "com.amazonaws.s3#ChecksumCRC32", "traits": { - "smithy.api#documentation": "

The Base64 encoded, 32-bit CRC32 checksum of the object. This checksum is only present if the object was uploaded\n with the object. For more information, see \n Checking object integrity in the Amazon S3 User Guide.

", + "smithy.api#documentation": "

The Base64 encoded, 32-bit CRC32 checksum of the object. This checksum is only present if the checksum was uploaded\n with the object. For more information, see \n Checking object integrity in the Amazon S3 User Guide.

", "smithy.api#httpHeader": "x-amz-checksum-crc32" } }, @@ -35575,6 +35649,27 @@ "smithy.api#documentation": "

Indicates whether this object has an active legal hold. This field is only returned if you have\n permission to view an object's legal hold status.

\n \n

This functionality is not supported for directory buckets.

\n
", "smithy.api#httpHeader": "x-amz-object-lock-legal-hold" } + }, + "ObjectLockEventHold": { + "target": "com.amazonaws.s3#ObjectLockEventHold", + "traits": { + "smithy.api#documentation": "

The event hold status for this object. This header is only returned if the requester has the\n s3:GetObjectRetention permission.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold" + } + }, + "ObjectLockEventHoldDurationDays": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationDays", + "traits": { + "smithy.api#documentation": "

The event hold duration in days for this object. Only returned when the event hold is\n enabled.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-days" + } + }, + "ObjectLockEventHoldDurationYears": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationYears", + "traits": { + "smithy.api#documentation": "

The event hold duration in years for this object. Only returned when the event hold is\n enabled.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-years" + } } }, "traits": { @@ -36714,6 +36809,27 @@ "smithy.api#documentation": "

Specifies whether a legal hold is in effect for this object. This header is only returned if the\n requester has the s3:GetObjectLegalHold permission. This header is not returned if the\n specified version of this object has never had a legal hold applied. For more information about S3\n Object Lock, see Object\n Lock.

\n \n

This functionality is not supported for directory buckets.

\n
", "smithy.api#httpHeader": "x-amz-object-lock-legal-hold" } + }, + "ObjectLockEventHold": { + "target": "com.amazonaws.s3#ObjectLockEventHold", + "traits": { + "smithy.api#documentation": "

The event hold status for this object. This header is only returned if the requester has the\n s3:GetObjectRetention permission.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold" + } + }, + "ObjectLockEventHoldDurationDays": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationDays", + "traits": { + "smithy.api#documentation": "

The event hold duration in days for this object. Only returned when the event hold is\n enabled.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-days" + } + }, + "ObjectLockEventHoldDurationYears": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationYears", + "traits": { + "smithy.api#documentation": "

The event hold duration in years for this object. Only returned when the event hold is\n enabled.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-years" + } } }, "traits": { @@ -37433,6 +37549,18 @@ "smithy.api#enumValue": "ObjectLockLegalHoldStatus" } }, + "ObjectLockEventHoldStatus": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "ObjectLockEventHoldStatus" + } + }, + "ObjectLockEventHoldDuration": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "ObjectLockEventHoldDuration" + } + }, "IntelligentTieringAccessTier": { "target": "smithy.api#Unit", "traits": { @@ -40897,6 +41025,29 @@ "com.amazonaws.s3#ObjectLockEnabledForBucket": { "type": "boolean" }, + "com.amazonaws.s3#ObjectLockEventHold": { + "type": "enum", + "members": { + "ON": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "ON" + } + }, + "OFF": { + "target": "smithy.api#Unit", + "traits": { + "smithy.api#enumValue": "OFF" + } + } + } + }, + "com.amazonaws.s3#ObjectLockEventHoldDurationDays": { + "type": "integer" + }, + "com.amazonaws.s3#ObjectLockEventHoldDurationYears": { + "type": "integer" + }, "com.amazonaws.s3#ObjectLockLegalHold": { "type": "structure", "members": { @@ -40965,6 +41116,18 @@ "traits": { "smithy.api#documentation": "

The date on which this Object Lock Retention will expire.

" } + }, + "EventHold": { + "target": "com.amazonaws.s3#ObjectLockEventHold", + "traits": { + "smithy.api#documentation": "

The event hold status for the object. Set to ON to enable an event hold or\n OFF to disable it.

" + } + }, + "EventHoldDuration": { + "target": "com.amazonaws.s3#EventHoldDuration", + "traits": { + "smithy.api#documentation": "

The event hold duration for the object. Specifies how long the object remains protected after the\n event hold is released.

" + } } }, "traits": { @@ -40994,7 +41157,7 @@ "DefaultRetention": { "target": "com.amazonaws.s3#DefaultRetention", "traits": { - "smithy.api#documentation": "

The default Object Lock retention mode and period that you want to apply to new objects placed in\n the specified bucket. Bucket settings require both a mode and a period. The period can be either\n Days or Years but you must select one. You cannot specify Days\n and Years at the same time.

" + "smithy.api#documentation": "

The default Object Lock retention settings for new objects in this bucket. You can\n specify:

\n \n

You can set one or both. You cannot use days and years in the same setting.

" } } }, @@ -44732,6 +44895,27 @@ "smithy.api#httpHeader": "x-amz-object-lock-legal-hold" } }, + "ObjectLockEventHold": { + "target": "com.amazonaws.s3#ObjectLockEventHold", + "traits": { + "smithy.api#documentation": "

Specifies the event hold status to apply to this object. Set to ON to enable or\n OFF to disable.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold" + } + }, + "ObjectLockEventHoldDurationDays": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationDays", + "traits": { + "smithy.api#documentation": "

Specifies the event hold duration in days to apply to this object. You cannot specify a\n duration in both days and years.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-days" + } + }, + "ObjectLockEventHoldDurationYears": { + "target": "com.amazonaws.s3#ObjectLockEventHoldDurationYears", + "traits": { + "smithy.api#documentation": "

Specifies the event hold duration in years to apply to this object. You cannot specify a\n duration in both days and years.

\n \n

This functionality is not supported for directory buckets.

\n
", + "smithy.api#httpHeader": "x-amz-object-lock-event-hold-duration-years" + } + }, "ExpectedBucketOwner": { "target": "com.amazonaws.s3#AccountId", "traits": { diff --git a/aws-models/sagemaker.json b/aws-models/sagemaker.json index d837579ca..2bf5b14fb 100644 --- a/aws-models/sagemaker.json +++ b/aws-models/sagemaker.json @@ -4822,6 +4822,98 @@ "smithy.api#pattern": "^[a-zA-Z0-9._-]+$" } }, + "com.amazonaws.sagemaker#AttachClusterNodeNetworkInterface": { + "type": "operation", + "input": { + "target": "com.amazonaws.sagemaker#AttachClusterNodeNetworkInterfaceRequest" + }, + "output": { + "target": "com.amazonaws.sagemaker#AttachClusterNodeNetworkInterfaceResponse" + }, + "errors": [ + { + "target": "com.amazonaws.sagemaker#ResourceLimitExceeded" + }, + { + "target": "com.amazonaws.sagemaker#ResourceNotFound" + } + ], + "traits": { + "smithy.api#documentation": "

Attaches an elastic network interface (ENI) to a node in a HyperPod cluster.

To use this operation, you must have the sagemaker:AttachClusterNodeNetworkInterface permission.

" + } + }, + "com.amazonaws.sagemaker#AttachClusterNodeNetworkInterfaceRequest": { + "type": "structure", + "members": { + "ClusterName": { + "target": "com.amazonaws.sagemaker#ClusterNameOrArn", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The name or Amazon Resource Name (ARN) of the SageMaker HyperPod cluster that contains the target node.

", + "smithy.api#required": {} + } + }, + "NodeId": { + "target": "com.amazonaws.sagemaker#ClusterNodeId", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The unique identifier of the cluster node to which you want to attach the network interface. The node must belong to your specified HyperPod cluster and cannot be part of a Restricted Instance Group (RIG).

", + "smithy.api#required": {} + } + }, + "NetworkInterfaceId": { + "target": "com.amazonaws.sagemaker#ClusterNetworkInterfaceId", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The unique identifier of the elastic network interface (ENI) to attach.

", + "smithy.api#required": {} + } + } + }, + "traits": { + "smithy.api#input": {} + } + }, + "com.amazonaws.sagemaker#AttachClusterNodeNetworkInterfaceResponse": { + "type": "structure", + "members": { + "ClusterArn": { + "target": "com.amazonaws.sagemaker#ClusterArn", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The Amazon Resource Name (ARN) of your SageMaker HyperPod cluster where the network interface attachment operation was performed.

", + "smithy.api#required": {} + } + }, + "NodeId": { + "target": "com.amazonaws.sagemaker#ClusterNodeId", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The unique identifier of the cluster node where your network interface was attached.

", + "smithy.api#required": {} + } + }, + "NetworkInterfaceId": { + "target": "com.amazonaws.sagemaker#ClusterNetworkInterfaceId", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The unique identifier of the elastic network interface (ENI) that was attached.

", + "smithy.api#required": {} + } + }, + "AttachmentId": { + "target": "com.amazonaws.sagemaker#ClusterNetworkInterfaceAttachmentId", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The unique identifier of the network interface attachment. Use this value to reference or detach the network interface later.

", + "smithy.api#required": {} + } + } + }, + "traits": { + "smithy.api#output": {} + } + }, "com.amazonaws.sagemaker#AttachClusterNodeVolume": { "type": "operation", "input": { @@ -12805,6 +12897,16 @@ "smithy.api#documentation": "

The network interface configuration for a Amazon SageMaker HyperPod cluster instance group.

" } }, + "com.amazonaws.sagemaker#ClusterNetworkInterfaceAttachmentId": { + "type": "string", + "traits": { + "smithy.api#length": { + "min": 1, + "max": 28 + }, + "smithy.api#pattern": "^eni-attach-[0-9a-f]{8}(?:[0-9a-f]{9})?$" + } + }, "com.amazonaws.sagemaker#ClusterNetworkInterfaceDetails": { "type": "structure", "members": { @@ -12819,6 +12921,16 @@ "smithy.api#documentation": "

The network interface configuration details for a Amazon SageMaker HyperPod cluster instance group.

" } }, + "com.amazonaws.sagemaker#ClusterNetworkInterfaceId": { + "type": "string", + "traits": { + "smithy.api#length": { + "min": 1, + "max": 21 + }, + "smithy.api#pattern": "^eni-[0-9a-f]{8}(?:[0-9a-f]{9})?$" + } + }, "com.amazonaws.sagemaker#ClusterNodeDetails": { "type": "structure", "members": { @@ -46004,6 +46116,47 @@ } } }, + "com.amazonaws.sagemaker#InstancePreference": { + "type": "structure", + "members": { + "InstanceType": { + "target": "com.amazonaws.sagemaker#TrainingInstanceType", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The ML compute instance type. An instance type can appear only once in an InstancePreferences list.

", + "smithy.api#required": {} + } + }, + "InstanceCount": { + "target": "com.amazonaws.sagemaker#TrainingInstanceCount", + "traits": { + "smithy.api#documentation": "

The number of instances to launch if this instance type is selected. Specify the instance count for the training job in one of the following two ways:

  1. Per preference \u2013 Set InstanceCount on every preference in the InstancePreferences list and don't set ResourceConfig$InstanceCount. Use this when each instance type needs a different number of instances to deliver equivalent compute.

  2. One count for the job \u2013 Set ResourceConfig$InstanceCount and omit it from every preference. SageMaker applies this to all instance types in the list.

For example, in a list of five preferences, either all five specify InstanceCount or none of them do. SageMaker rejects requests that set InstanceCount on only some preferences, that set it both per preference and in ResourceConfig, or that omit it in both places.

" + } + }, + "TrainingPlanArns": { + "target": "com.amazonaws.sagemaker#TrainingPlanArnList", + "traits": { + "smithy.api#documentation": "

The Amazon Resource Name (ARN) of a training plan to use if this instance type is selected. The plan's instance type must match InstanceType. A preference with a training plan uses that plan's reserved capacity; a preference without one uses on-demand capacity. Per-preference TrainingPlanArns is mutually exclusive with the job-level TrainingPlanArn in ResourceConfig.

" + } + } + }, + "traits": { + "smithy.api#documentation": "

A candidate instance type preference in an InstancePreferences list.

" + } + }, + "com.amazonaws.sagemaker#InstancePreferenceList": { + "type": "list", + "member": { + "target": "com.amazonaws.sagemaker#InstancePreference" + }, + "traits": { + "smithy.api#documentation": "Ordered list of candidate instance types, in priority order.", + "smithy.api#length": { + "min": 1, + "max": 5 + } + } + }, "com.amazonaws.sagemaker#InstanceRequirementsEniConfiguration": { "type": "structure", "members": { @@ -58305,7 +58458,7 @@ "traits": { "smithy.api#documentation": "Maximum job scheduler pending time in seconds.", "smithy.api#range": { - "min": 7200, + "min": 1800, "max": 2419200 } } @@ -67267,6 +67420,24 @@ "traits": { "smithy.api#documentation": "

The Amazon Web Services Key Management Service (Amazon Web Services KMS) key that Amazon SageMaker uses to encrypt data on the storage volume attached to the ML compute instance(s) that run the processing job.

Certain Nitro-based instances include local storage, dependent on the instance type. Local storage volumes are encrypted using a hardware module on the instance. You can't request a VolumeKmsKeyId when using an instance type with local storage.

For a list of instance types that support local instance storage, see Instance Store Volumes.

For more information about local instance storage encryption, see SSD Instance Store Volumes.

" } + }, + "InstancePreferences": { + "target": "com.amazonaws.sagemaker#ProcessingInstancePreferenceList", + "traits": { + "smithy.api#documentation": "

An ordered list of ML compute instance types for the processing job, in priority order. Amazon SageMaker launches the job on the first instance type in the list that has available capacity. If capacity is insufficient, Amazon SageMaker evaluates the next instance type in the list. Exactly one instance type is selected for the job.

InstancePreferences is mutually exclusive with InstanceType.

" + } + }, + "SelectedInstanceType": { + "target": "com.amazonaws.sagemaker#ProcessingInstanceType", + "traits": { + "smithy.api#documentation": "

The instance type that Amazon SageMaker selected for the job from InstancePreferences. Returned by DescribeProcessingJob after an instance type is selected. This field is read-only and isn't accepted in CreateProcessingJob requests.

" + } + }, + "SelectedInstanceCount": { + "target": "com.amazonaws.sagemaker#ProcessingInstanceCount", + "traits": { + "smithy.api#documentation": "

The number of instances of SelectedInstanceType that the job launched with. The job is billed for this instance type and count. Returned by DescribeProcessingJob after an instance type is selected. This field is read-only and isn't accepted in CreateProcessingJob requests.

" + } } }, "traits": { @@ -67379,6 +67550,41 @@ } } }, + "com.amazonaws.sagemaker#ProcessingInstancePreference": { + "type": "structure", + "members": { + "InstanceType": { + "target": "com.amazonaws.sagemaker#ProcessingInstanceType", + "traits": { + "smithy.api#clientOptional": {}, + "smithy.api#documentation": "

The ML compute instance type. An instance type can appear only once in an InstancePreferences list.

", + "smithy.api#required": {} + } + }, + "InstanceCount": { + "target": "com.amazonaws.sagemaker#ProcessingInstanceCount", + "traits": { + "smithy.api#documentation": "

The number of instances to launch if this instance type is selected. Specify the instance count for the processing job in one of the following two ways:

  1. Per preference \u2013 Set InstanceCount on every preference in the InstancePreferences list and don't set ProcessingClusterConfig$InstanceCount. Use this when each instance type needs a different number of instances to deliver equivalent compute.

  2. One count for the job \u2013 Set ProcessingClusterConfig$InstanceCount and omit it from every preference. Amazon SageMaker applies this to all instance types in the list.

For example, in a list of five preferences, either all five specify InstanceCount or none of them do. Amazon SageMaker rejects requests that set InstanceCount on only some preferences, that set it both per preference and in ProcessingClusterConfig, or that omit it in both places.

" + } + } + }, + "traits": { + "smithy.api#documentation": "

A candidate instance type preference in a processing InstancePreferences list.

" + } + }, + "com.amazonaws.sagemaker#ProcessingInstancePreferenceList": { + "type": "list", + "member": { + "target": "com.amazonaws.sagemaker#ProcessingInstancePreference" + }, + "traits": { + "smithy.api#documentation": "Ordered list of candidate instance types, in priority order.", + "smithy.api#length": { + "min": 1, + "max": 5 + } + } + }, "com.amazonaws.sagemaker#ProcessingInstanceType": { "type": "enum", "members": { @@ -73876,6 +74082,24 @@ "traits": { "smithy.api#documentation": "

Configuration for how training job instances are placed and allocated within UltraServers. Only applicable for UltraServer capacity.

" } + }, + "InstancePreferences": { + "target": "com.amazonaws.sagemaker#InstancePreferenceList", + "traits": { + "smithy.api#documentation": "

An ordered list of ML compute instance types for the training job, in priority order. SageMaker launches the training job on the first instance type in the list that has available capacity. If capacity is insufficient, SageMaker evaluates the next instance type in the preferred list. Exactly one instance type is selected for the job.

InstancePreferences is mutually exclusive with InstanceType, InstanceGroups, InstancePlacementConfig, and EnableManagedSpotTraining, and supports only Flexible Training Plans (FTP) and On-Demand capacity.

" + } + }, + "SelectedInstanceType": { + "target": "com.amazonaws.sagemaker#TrainingInstanceType", + "traits": { + "smithy.api#documentation": "

The instance type that SageMaker selected for the job from the provided InstancePreferences. The job is billed for this instance type and count. Returned by DescribeTrainingJob after an instance type is selected. This field is read-only and isn't accepted in CreateTrainingJob requests.

" + } + }, + "SelectedInstanceCount": { + "target": "com.amazonaws.sagemaker#TrainingInstanceCount", + "traits": { + "smithy.api#documentation": "

The number of instances of SelectedInstanceType that the training job launched with. The job is billed for this instance type and count. Returned by DescribeTrainingJob after an instance type is selected. This field is read-only and isn't accepted in CreateTrainingJob requests.

" + } } }, "traits": { @@ -74871,6 +75095,9 @@ { "target": "com.amazonaws.sagemaker#AssociateTrialComponent" }, + { + "target": "com.amazonaws.sagemaker#AttachClusterNodeNetworkInterface" + }, { "target": "com.amazonaws.sagemaker#AttachClusterNodeVolume" }, @@ -81118,7 +81345,7 @@ "MaxPendingTimeInSeconds": { "target": "com.amazonaws.sagemaker#MaxPendingTimeInSeconds", "traits": { - "smithy.api#documentation": "

The maximum length of time, in seconds, that a training or compilation job can be pending before it is stopped.

When working with training jobs that use capacity from training plans, not all Pending job states count against the MaxPendingTimeInSeconds limit. The following scenarios do not increment the MaxPendingTimeInSeconds counter:

MaxPendingTimeInSeconds only increments when jobs are actively waiting for capacity in an Active plan.

" + "smithy.api#documentation": "

The maximum length of time, in seconds, that a training or compilation job can be pending before it is stopped.

When working with training jobs that use capacity from training plans, not all Pending job states count against the MaxPendingTimeInSeconds limit. The following scenarios do not increment the MaxPendingTimeInSeconds counter:

MaxPendingTimeInSeconds only increments when jobs are actively waiting for capacity in an Active plan.

" } } }, @@ -84663,6 +84890,19 @@ "smithy.api#pattern": "^arn:aws[a-z\\-]*:sagemaker:[a-z0-9\\-]*:[0-9]{12}:training-plan/" } }, + "com.amazonaws.sagemaker#TrainingPlanArnList": { + "type": "list", + "member": { + "target": "com.amazonaws.sagemaker#TrainingPlanArn" + }, + "traits": { + "smithy.api#documentation": "Training plan ARNs for a single instance preference.", + "smithy.api#length": { + "min": 1, + "max": 1 + } + } + }, "com.amazonaws.sagemaker#TrainingPlanArns": { "type": "list", "member": { diff --git a/crates/fakecloud-conformance/tests/cloudtrail.rs b/crates/fakecloud-conformance/tests/cloudtrail.rs index c536a6c69..eb92cd531 100644 --- a/crates/fakecloud-conformance/tests/cloudtrail.rs +++ b/crates/fakecloud-conformance/tests/cloudtrail.rs @@ -15,7 +15,7 @@ use helpers::TestServer; #[test_action("cloudtrail", "CreateChannel", checksum = "038a130e")] #[test_action("cloudtrail", "CreateDashboard", checksum = "d02fd204")] #[test_action("cloudtrail", "CreateEventDataStore", checksum = "85a28968")] -#[test_action("cloudtrail", "CreateTrail", checksum = "66c8b2d1")] +#[test_action("cloudtrail", "CreateTrail", checksum = "7d910ed8")] #[test_action("cloudtrail", "DeleteChannel", checksum = "c4c5291b")] #[test_action("cloudtrail", "DeleteDashboard", checksum = "79584041")] #[test_action("cloudtrail", "DeleteEventDataStore", checksum = "4472b697")] @@ -27,7 +27,7 @@ use helpers::TestServer; checksum = "d717211e" )] #[test_action("cloudtrail", "DescribeQuery", checksum = "0b31facc")] -#[test_action("cloudtrail", "DescribeTrails", checksum = "17f76359")] +#[test_action("cloudtrail", "DescribeTrails", checksum = "3cd7b259")] #[test_action("cloudtrail", "DisableFederation", checksum = "c69212d4")] #[test_action("cloudtrail", "EnableFederation", checksum = "9e122fb1")] #[test_action("cloudtrail", "GenerateQuery", checksum = "df0f9127")] @@ -40,7 +40,7 @@ use helpers::TestServer; #[test_action("cloudtrail", "GetInsightSelectors", checksum = "6fb75598")] #[test_action("cloudtrail", "GetQueryResults", checksum = "65b94755")] #[test_action("cloudtrail", "GetResourcePolicy", checksum = "69887b16")] -#[test_action("cloudtrail", "GetTrail", checksum = "bf794d13")] +#[test_action("cloudtrail", "GetTrail", checksum = "0847efe7")] #[test_action("cloudtrail", "GetTrailStatus", checksum = "c0e5cb6f")] #[test_action("cloudtrail", "ListChannels", checksum = "90f1dffe")] #[test_action("cloudtrail", "ListDashboards", checksum = "8b971717")] @@ -56,7 +56,7 @@ use helpers::TestServer; #[test_action("cloudtrail", "LookupEvents", checksum = "8371a1f2")] #[test_action("cloudtrail", "PutEventConfiguration", checksum = "0c49cab9")] #[test_action("cloudtrail", "PutEventSelectors", checksum = "da42429f")] -#[test_action("cloudtrail", "PutInsightSelectors", checksum = "80aee099")] +#[test_action("cloudtrail", "PutInsightSelectors", checksum = "297b3261")] #[test_action("cloudtrail", "PutResourcePolicy", checksum = "d9935a52")] #[test_action( "cloudtrail", @@ -77,7 +77,7 @@ use helpers::TestServer; #[test_action("cloudtrail", "UpdateChannel", checksum = "c8510015")] #[test_action("cloudtrail", "UpdateDashboard", checksum = "44eafd97")] #[test_action("cloudtrail", "UpdateEventDataStore", checksum = "27a96ae1")] -#[test_action("cloudtrail", "UpdateTrail", checksum = "e3cf00bd")] +#[test_action("cloudtrail", "UpdateTrail", checksum = "592e538a")] #[tokio::test] async fn cloudtrail_probe() { let _server = TestServer::start().await; diff --git a/crates/fakecloud-conformance/tests/ec2.rs b/crates/fakecloud-conformance/tests/ec2.rs index 2d0f88e1a..e7cf9c9f8 100644 --- a/crates/fakecloud-conformance/tests/ec2.rs +++ b/crates/fakecloud-conformance/tests/ec2.rs @@ -2625,7 +2625,7 @@ async fn ec2_describe_instance_status() { .any(|x| x.instance_id() == Some(id.as_str()))); } -#[test_action("ec2", "DescribeInstanceTypes", checksum = "b10abc8e")] +#[test_action("ec2", "DescribeInstanceTypes", checksum = "3d9f9d27")] #[tokio::test] async fn ec2_describe_instance_types() { let s = TestServer::start().await; @@ -2972,7 +2972,7 @@ async fn make_vol(c: &aws_sdk_ec2::Client) -> String { .to_string() } -#[test_action("ec2", "CreateVolume", checksum = "01037f49")] +#[test_action("ec2", "CreateVolume", checksum = "110701d7")] #[tokio::test] async fn ec2_create_volume() { let s = TestServer::start().await; @@ -2989,7 +2989,7 @@ async fn ec2_create_volume() { assert_eq!(r.size(), Some(10)); } -#[test_action("ec2", "DescribeVolumes", checksum = "9dfe1d7b")] +#[test_action("ec2", "DescribeVolumes", checksum = "7e1e5357")] #[tokio::test] async fn ec2_describe_volumes() { let s = TestServer::start().await; @@ -3585,7 +3585,7 @@ async fn make_ami(c: &aws_sdk_ec2::Client) -> String { .to_string() } -#[test_action("ec2", "CreateImage", checksum = "32e8dd50")] +#[test_action("ec2", "CreateImage", checksum = "cb26117a")] #[tokio::test] async fn ec2_create_image() { let s = TestServer::start().await; @@ -10820,7 +10820,7 @@ async fn ec2_copy_fpga_image() { .unwrap(); } -#[test_action("ec2", "CopyVolumes", checksum = "fb31e0b4")] +#[test_action("ec2", "CopyVolumes", checksum = "66f62bba")] #[tokio::test] async fn ec2_copy_volumes() { let s = TestServer::start().await; diff --git a/crates/fakecloud-conformance/tests/ecs.rs b/crates/fakecloud-conformance/tests/ecs.rs index fda3444c2..f0d5f2f26 100644 --- a/crates/fakecloud-conformance/tests/ecs.rs +++ b/crates/fakecloud-conformance/tests/ecs.rs @@ -1992,7 +1992,7 @@ fn primary_eg_container() -> aws_sdk_ecs::types::ExpressGatewayContainer { .unwrap() } -#[test_action("ecs", "CreateExpressGatewayService", checksum = "7b4cdec8")] +#[test_action("ecs", "CreateExpressGatewayService", checksum = "a61aa54e")] #[tokio::test] async fn ecs_create_express_gateway_service() { let server = TestServer::start().await; @@ -2010,7 +2010,7 @@ async fn ecs_create_express_gateway_service() { assert!(resp.service().is_some()); } -#[test_action("ecs", "DescribeExpressGatewayService", checksum = "9aa55c32")] +#[test_action("ecs", "DescribeExpressGatewayService", checksum = "aa739a71")] #[tokio::test] async fn ecs_describe_express_gateway_service() { let server = TestServer::start().await; @@ -2040,7 +2040,7 @@ async fn ecs_describe_express_gateway_service() { assert!(resp.service().is_some()); } -#[test_action("ecs", "UpdateExpressGatewayService", checksum = "a141e8d8")] +#[test_action("ecs", "UpdateExpressGatewayService", checksum = "03be7c30")] #[tokio::test] async fn ecs_update_express_gateway_service() { let server = TestServer::start().await; @@ -2071,7 +2071,7 @@ async fn ecs_update_express_gateway_service() { assert!(resp.service().is_some()); } -#[test_action("ecs", "DeleteExpressGatewayService", checksum = "04d162c4")] +#[test_action("ecs", "DeleteExpressGatewayService", checksum = "b1113f96")] #[tokio::test] async fn ecs_delete_express_gateway_service() { let server = TestServer::start().await; diff --git a/crates/fakecloud-conformance/tests/s3.rs b/crates/fakecloud-conformance/tests/s3.rs index 4dc57026e..cdff75519 100644 --- a/crates/fakecloud-conformance/tests/s3.rs +++ b/crates/fakecloud-conformance/tests/s3.rs @@ -50,9 +50,9 @@ async fn s3_bucket_lifecycle() { // -- Object CRUD -- -#[test_action("s3", "PutObject", checksum = "665467c9")] -#[test_action("s3", "GetObject", checksum = "4882765a")] -#[test_action("s3", "HeadObject", checksum = "049f72ca")] +#[test_action("s3", "PutObject", checksum = "e0849b40")] +#[test_action("s3", "GetObject", checksum = "e66696e9")] +#[test_action("s3", "HeadObject", checksum = "df065b6b")] #[test_action("s3", "DeleteObject", checksum = "b50d71d4")] #[tokio::test] async fn s3_object_crud() { @@ -104,7 +104,7 @@ async fn s3_object_crud() { // -- CopyObject -- -#[test_action("s3", "CopyObject", checksum = "6db54704")] +#[test_action("s3", "CopyObject", checksum = "5f7a4b66")] #[tokio::test] async fn s3_copy_object() { let server = TestServer::start().await; @@ -432,8 +432,8 @@ async fn s3_object_acl() { // -- Object retention + legal hold -- -#[test_action("s3", "PutObjectRetention", checksum = "16e8bfef")] -#[test_action("s3", "GetObjectRetention", checksum = "cd7095c1")] +#[test_action("s3", "PutObjectRetention", checksum = "bb7cc7ef")] +#[test_action("s3", "GetObjectRetention", checksum = "d5e69dc0")] #[tokio::test] async fn s3_object_retention() { let server = TestServer::start().await; @@ -698,8 +698,8 @@ async fn s3_bucket_cors() { // -- Bucket notification configuration -- -#[test_action("s3", "PutBucketNotificationConfiguration", checksum = "7df12619")] -#[test_action("s3", "GetBucketNotificationConfiguration", checksum = "7ce92d6d")] +#[test_action("s3", "PutBucketNotificationConfiguration", checksum = "864b4fc3")] +#[test_action("s3", "GetBucketNotificationConfiguration", checksum = "86a1129f")] #[tokio::test] async fn s3_bucket_notification() { let server = TestServer::start().await; @@ -1048,8 +1048,8 @@ async fn s3_bucket_policy() { // -- Object lock configuration -- -#[test_action("s3", "PutObjectLockConfiguration", checksum = "36a5a1a7")] -#[test_action("s3", "GetObjectLockConfiguration", checksum = "8cbd3dcf")] +#[test_action("s3", "PutObjectLockConfiguration", checksum = "b7199119")] +#[test_action("s3", "GetObjectLockConfiguration", checksum = "eb00f48c")] #[tokio::test] async fn s3_object_lock_configuration() { let server = TestServer::start().await; @@ -1204,8 +1204,8 @@ async fn s3_bucket_ownership_controls() { // -- Bucket inventory configuration -- -#[test_action("s3", "PutBucketInventoryConfiguration", checksum = "f1431dd8")] -#[test_action("s3", "GetBucketInventoryConfiguration", checksum = "3e191949")] +#[test_action("s3", "PutBucketInventoryConfiguration", checksum = "5379f8ec")] +#[test_action("s3", "GetBucketInventoryConfiguration", checksum = "5d84300c")] #[test_action("s3", "DeleteBucketInventoryConfiguration", checksum = "5fb3b7de")] #[tokio::test] async fn s3_bucket_inventory() { @@ -1273,7 +1273,7 @@ async fn s3_bucket_inventory() { // -- Multipart upload -- -#[test_action("s3", "CreateMultipartUpload", checksum = "f2c09ed2")] +#[test_action("s3", "CreateMultipartUpload", checksum = "de36793d")] #[test_action("s3", "UploadPart", checksum = "1a454d97")] #[test_action("s3", "CompleteMultipartUpload", checksum = "33dfb649")] #[test_action("s3", "ListParts", checksum = "d56ef91f")] @@ -1657,7 +1657,7 @@ async fn s3_metrics_configuration_lifecycle() { .unwrap(); } -#[test_action("s3", "ListBucketInventoryConfigurations", checksum = "0088bbbb")] +#[test_action("s3", "ListBucketInventoryConfigurations", checksum = "b97f3ee2")] #[tokio::test] async fn s3_list_bucket_inventory_configurations() { let server = TestServer::start().await; diff --git a/crates/fakecloud-e2e/tests/sagemaker.rs b/crates/fakecloud-e2e/tests/sagemaker.rs index 89dddda7e..caf41b8aa 100644 --- a/crates/fakecloud-e2e/tests/sagemaker.rs +++ b/crates/fakecloud-e2e/tests/sagemaker.rs @@ -417,6 +417,93 @@ async fn sagemaker_batch_cluster_nodes_round_trip() { assert_eq!(listed.cluster_node_summaries().len(), 1); } +// AttachClusterNodeNetworkInterface attaches an ENI to a node added by +// BatchAddClusterNodes. aws-sdk-sagemaker predates the operation, so it is +// driven over the raw awsJson1.1 wire. +#[tokio::test] +async fn sagemaker_attach_cluster_node_network_interface() { + use aws_sdk_sagemaker::types::AddClusterNodeSpecification; + + let server = TestServer::start().await; + let client = sagemaker_client(&server).await; + + client + .batch_add_cluster_nodes() + .cluster_name("hp-eni") + .nodes_to_add( + AddClusterNodeSpecification::builder() + .instance_group_name("workers") + .increment_target_count_by(1) + .build() + .unwrap(), + ) + .send() + .await + .expect("batch_add_cluster_nodes"); + let listed = client + .list_cluster_nodes() + .cluster_name("hp-eni") + .send() + .await + .expect("list_cluster_nodes"); + let instance_id = listed.cluster_node_summaries()[0] + .instance_id() + .expect("instance_id") + .to_string(); + + let http = reqwest::Client::new(); + let attach = |node: String, eni: &'static str| { + let req = http + .post(server.endpoint()) + .header("content-type", "application/x-amz-json-1.1") + .header( + "x-amz-target", + "SageMaker.AttachClusterNodeNetworkInterface", + ) + .header( + "authorization", + "AWS4-HMAC-SHA256 Credential=test/20260101/us-east-1/sagemaker/aws4_request, \ + SignedHeaders=host, Signature=0", + ) + .body( + serde_json::json!({ + "ClusterName": "hp-eni", + "NodeId": node, + "NetworkInterfaceId": eni, + }) + .to_string(), + ); + async move { + let resp = req.send().await.expect("request sent"); + let status = resp.status(); + let body: serde_json::Value = resp.json().await.expect("json body"); + (status, body) + } + }; + + let (status, body) = attach(instance_id.clone(), "eni-0123456789abcdef0").await; + assert_eq!(status, 200, "attach failed: {body}"); + assert_eq!(body["NodeId"], instance_id.as_str()); + assert_eq!(body["NetworkInterfaceId"], "eni-0123456789abcdef0"); + assert!(body["ClusterArn"].as_str().unwrap().contains(":cluster/")); + let attachment_id = body["AttachmentId"].as_str().unwrap().to_string(); + assert!(attachment_id.starts_with("eni-attach-"), "{attachment_id}"); + + // Re-attaching the same ENI to the same node returns the same attachment. + let (status, again) = attach(instance_id, "eni-0123456789abcdef0").await; + assert_eq!(status, 200, "re-attach failed: {again}"); + assert_eq!(again["AttachmentId"], attachment_id.as_str()); + + // An unknown node is ResourceNotFound. + let (status, missing) = + attach("i-0ffffffffffffffff".to_string(), "eni-0aaaaaaaaaaaaaaaa").await; + assert_eq!(status, 404, "{missing}"); + assert!( + missing.to_string().contains("ResourceNotFound"), + "{missing}" + ); +} + // AssociateTrialComponent makes a component visible under a scoped // ListTrialComponents(TrialName=…); DisassociateTrialComponent removes it. #[tokio::test] diff --git a/crates/fakecloud-sagemaker/src/generated.rs b/crates/fakecloud-sagemaker/src/generated.rs index b3f8d3684..3b4a1febe 100644 --- a/crates/fakecloud-sagemaker/src/generated.rs +++ b/crates/fakecloud-sagemaker/src/generated.rs @@ -226,6 +226,103 @@ pub static OPS: &[OpMeta] = &[ req_out: &[], req_elem: &[], }, + OpMeta { + op: "AttachClusterNodeNetworkInterface", + verb: Verb::Action, + family: "ClusterNodeNetworkInterface", + key_member: "", + arn_path: "cluster-node-network-interface", + has_input: true, + errors: &["ResourceLimitExceeded", "ResourceNotFound"], + rules: &[ + Rule { + wire: "ClusterName", + req: true, + kind: K::Str, + min_len: Some(0), + max_len: Some(256), + min_val: None, + max_val: None, + enums: &[], + }, + Rule { + wire: "NodeId", + req: true, + kind: K::Str, + min_len: Some(1), + max_len: Some(256), + min_val: None, + max_val: None, + enums: &[], + }, + Rule { + wire: "NetworkInterfaceId", + req: true, + kind: K::Str, + min_len: Some(1), + max_len: Some(21), + min_val: None, + max_val: None, + enums: &[], + }, + ], + omembers: &[ + ("ClusterArn", K::Str), + ("NodeId", K::Str), + ("NetworkInterfaceId", K::Str), + ("AttachmentId", K::Str), + ], + list_field: None, + list_elems: &[], + list_scalar: false, + req_out: &[ + Field { + wire: "ClusterArn", + kind: K::Str, + enums: &[], + min_len: Some(0), + min_val: None, + list_min: None, + elem_kind: K::Str, + is_union: false, + children: &[], + }, + Field { + wire: "NodeId", + kind: K::Str, + enums: &[], + min_len: Some(1), + min_val: None, + list_min: None, + elem_kind: K::Str, + is_union: false, + children: &[], + }, + Field { + wire: "NetworkInterfaceId", + kind: K::Str, + enums: &[], + min_len: Some(1), + min_val: None, + list_min: None, + elem_kind: K::Str, + is_union: false, + children: &[], + }, + Field { + wire: "AttachmentId", + kind: K::Str, + enums: &[], + min_len: Some(1), + min_val: None, + list_min: None, + elem_kind: K::Str, + is_union: false, + children: &[], + }, + ], + req_elem: &[], + }, OpMeta { op: "AttachClusterNodeVolume", verb: Verb::Action, @@ -3979,6 +4076,16 @@ pub static OPS: &[OpMeta] = &[ max_val: None, enums: &[], }, + Rule { + wire: "KmsKeyId", + req: false, + kind: K::Str, + min_len: Some(0), + max_len: Some(2048), + min_val: None, + max_val: None, + enums: &[], + }, Rule { wire: "ModelRegistrationMode", req: false, @@ -5085,6 +5192,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g6.16xlarge", "ml.g6.24xlarge", "ml.g6.48xlarge", + "ml.g7e.2xlarge", + "ml.g7e.4xlarge", + "ml.g7e.8xlarge", + "ml.g7e.12xlarge", + "ml.g7e.24xlarge", + "ml.g7e.48xlarge", "ml.p5.4xlarge", "ml.p5en.48xlarge", "ml.g6e.xlarge", @@ -5382,6 +5495,19 @@ pub static OPS: &[OpMeta] = &[ "ml.trn1.2xlarge", "ml.trn1.32xlarge", "ml.trn1n.32xlarge", + "ml.p6-b200.48xlarge", + "ml.g7e.2xlarge", + "ml.g7e.4xlarge", + "ml.g7e.8xlarge", + "ml.g7e.12xlarge", + "ml.g7e.24xlarge", + "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], }, Rule { @@ -5444,6 +5570,16 @@ pub static OPS: &[OpMeta] = &[ max_val: None, enums: &[], }, + Rule { + wire: "TrainingPlanArns", + req: false, + kind: K::List, + min_len: Some(0), + max_len: Some(1), + min_val: None, + max_val: None, + enums: &[], + }, ], omembers: &[("OptimizationJobArn", K::Str)], list_field: None, @@ -5534,7 +5670,7 @@ pub static OPS: &[OpMeta] = &[ max_len: None, min_val: None, max_val: None, - enums: &["IAM"], + enums: &["IAM", "IDC"], }, Rule { wire: "ClientToken", @@ -8881,6 +9017,7 @@ pub static OPS: &[OpMeta] = &[ ("Recommendations", K::List), ("RoleArn", K::Str), ("ComputeSpec", K::Struct), + ("AdapterSource", K::Struct), ("CreationTime", K::Ts), ("StartTime", K::Ts), ("EndTime", K::Ts), @@ -8894,6 +9031,7 @@ pub static OPS: &[OpMeta] = &[ ("DeploymentConfiguration", K::Struct), ("AIBenchmarkJobArn", K::Str), ("ExpectedPerformance", K::List), + ("AdapterDetails", K::Struct), ], list_scalar: false, req_out: &[ @@ -9374,6 +9512,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g7e.12xlarge", "ml.g7e.24xlarge", "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -11130,6 +11274,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g7e.12xlarge", "ml.g7e.24xlarge", "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -13653,6 +13803,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g7e.12xlarge", "ml.g7e.24xlarge", "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", "ml.p4d.24xlarge", "ml.c7g.large", "ml.c7g.xlarge", @@ -14019,6 +14175,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g7e.12xlarge", "ml.g7e.24xlarge", "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", "ml.p4d.24xlarge", "ml.c7g.large", "ml.c7g.xlarge", @@ -15069,6 +15231,7 @@ pub static OPS: &[OpMeta] = &[ ("ArtifactStoreUri", K::Str), ("MlflowVersion", K::Str), ("RoleArn", K::Str), + ("KmsKeyId", K::Str), ("Status", K::Str), ("ModelRegistrationMode", K::Str), ("AccountDefaultStatus", K::Str), @@ -15551,6 +15714,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g7e.12xlarge", "ml.g7e.24xlarge", "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -16177,6 +16346,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g7e.12xlarge", "ml.g7e.24xlarge", "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -16824,6 +16999,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g7e.12xlarge", "ml.g7e.24xlarge", "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -17081,6 +17262,7 @@ pub static OPS: &[OpMeta] = &[ ("RoleArn", K::Str), ("StoppingCondition", K::Struct), ("VpcConfig", K::Struct), + ("TrainingPlanArns", K::List), ], list_field: Some("OptimizationConfigs"), list_elems: &[ @@ -17210,6 +17392,19 @@ pub static OPS: &[OpMeta] = &[ "ml.trn1.2xlarge", "ml.trn1.32xlarge", "ml.trn1n.32xlarge", + "ml.p6-b200.48xlarge", + "ml.g7e.2xlarge", + "ml.g7e.4xlarge", + "ml.g7e.8xlarge", + "ml.g7e.12xlarge", + "ml.g7e.24xlarge", + "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -17313,6 +17508,7 @@ pub static OPS: &[OpMeta] = &[ ("EnableAutoMinorVersionUpgrade", K::Bool), ("CurrentVersionEolDate", K::Ts), ("AvailableUpgrade", K::Struct), + ("IdcConfig", K::Struct), ], list_field: None, list_elems: &[], @@ -17518,169 +17714,17 @@ pub static OPS: &[OpMeta] = &[ list_min: None, elem_kind: K::Str, is_union: false, - children: &[ - Field { - wire: "InstanceCount", - kind: K::Int, - enums: &[], - min_len: None, - min_val: Some(1), - list_min: None, - elem_kind: K::Str, - is_union: false, - children: &[], - }, - Field { - wire: "InstanceType", - kind: K::Str, - enums: &[ - "ml.t3.medium", - "ml.t3.large", - "ml.t3.xlarge", - "ml.t3.2xlarge", - "ml.m4.xlarge", - "ml.m4.2xlarge", - "ml.m4.4xlarge", - "ml.m4.10xlarge", - "ml.m4.16xlarge", - "ml.c4.xlarge", - "ml.c4.2xlarge", - "ml.c4.4xlarge", - "ml.c4.8xlarge", - "ml.p2.xlarge", - "ml.p2.8xlarge", - "ml.p2.16xlarge", - "ml.p3.2xlarge", - "ml.p3.8xlarge", - "ml.p3.16xlarge", - "ml.c5.xlarge", - "ml.c5.2xlarge", - "ml.c5.4xlarge", - "ml.c5.9xlarge", - "ml.c5.18xlarge", - "ml.m5.large", - "ml.m5.xlarge", - "ml.m5.2xlarge", - "ml.m5.4xlarge", - "ml.m5.12xlarge", - "ml.m5.24xlarge", - "ml.r5.large", - "ml.r5.xlarge", - "ml.r5.2xlarge", - "ml.r5.4xlarge", - "ml.r5.8xlarge", - "ml.r5.12xlarge", - "ml.r5.16xlarge", - "ml.r5.24xlarge", - "ml.g4dn.xlarge", - "ml.g4dn.2xlarge", - "ml.g4dn.4xlarge", - "ml.g4dn.8xlarge", - "ml.g4dn.12xlarge", - "ml.g4dn.16xlarge", - "ml.g5.xlarge", - "ml.g5.2xlarge", - "ml.g5.4xlarge", - "ml.g5.8xlarge", - "ml.g5.16xlarge", - "ml.g5.12xlarge", - "ml.g5.24xlarge", - "ml.g5.48xlarge", - "ml.r5d.large", - "ml.r5d.xlarge", - "ml.r5d.2xlarge", - "ml.r5d.4xlarge", - "ml.r5d.8xlarge", - "ml.r5d.12xlarge", - "ml.r5d.16xlarge", - "ml.r5d.24xlarge", - "ml.g6.xlarge", - "ml.g6.2xlarge", - "ml.g6.4xlarge", - "ml.g6.8xlarge", - "ml.g6.12xlarge", - "ml.g6.16xlarge", - "ml.g6.24xlarge", - "ml.g6.48xlarge", - "ml.g6e.xlarge", - "ml.g6e.2xlarge", - "ml.g6e.4xlarge", - "ml.g6e.8xlarge", - "ml.g6e.12xlarge", - "ml.g6e.16xlarge", - "ml.g6e.24xlarge", - "ml.g6e.48xlarge", - "ml.m6i.large", - "ml.m6i.xlarge", - "ml.m6i.2xlarge", - "ml.m6i.4xlarge", - "ml.m6i.8xlarge", - "ml.m6i.12xlarge", - "ml.m6i.16xlarge", - "ml.m6i.24xlarge", - "ml.m6i.32xlarge", - "ml.c6i.xlarge", - "ml.c6i.2xlarge", - "ml.c6i.4xlarge", - "ml.c6i.8xlarge", - "ml.c6i.12xlarge", - "ml.c6i.16xlarge", - "ml.c6i.24xlarge", - "ml.c6i.32xlarge", - "ml.m7i.large", - "ml.m7i.xlarge", - "ml.m7i.2xlarge", - "ml.m7i.4xlarge", - "ml.m7i.8xlarge", - "ml.m7i.12xlarge", - "ml.m7i.16xlarge", - "ml.m7i.24xlarge", - "ml.m7i.48xlarge", - "ml.c7i.large", - "ml.c7i.xlarge", - "ml.c7i.2xlarge", - "ml.c7i.4xlarge", - "ml.c7i.8xlarge", - "ml.c7i.12xlarge", - "ml.c7i.16xlarge", - "ml.c7i.24xlarge", - "ml.c7i.48xlarge", - "ml.r7i.large", - "ml.r7i.xlarge", - "ml.r7i.2xlarge", - "ml.r7i.4xlarge", - "ml.r7i.8xlarge", - "ml.r7i.12xlarge", - "ml.r7i.16xlarge", - "ml.r7i.24xlarge", - "ml.r7i.48xlarge", - "ml.p5.4xlarge", - "ml.g7e.2xlarge", - "ml.g7e.4xlarge", - "ml.g7e.8xlarge", - "ml.g7e.12xlarge", - "ml.g7e.24xlarge", - "ml.g7e.48xlarge", - ], - min_len: None, - min_val: None, - list_min: None, - elem_kind: K::Str, - is_union: false, - children: &[], - }, - Field { - wire: "VolumeSizeInGB", - kind: K::Int, - enums: &[], - min_len: None, - min_val: Some(1), - list_min: None, - elem_kind: K::Str, - is_union: false, - children: &[], - }, - ], + children: &[Field { + wire: "VolumeSizeInGB", + kind: K::Int, + enums: &[], + min_len: None, + min_val: Some(1), + list_min: None, + elem_kind: K::Str, + is_union: false, + children: &[], + }], }], }, Field { @@ -18725,6 +18769,14 @@ pub static OPS: &[OpMeta] = &[ "ml.g6.16xlarge", "ml.g6.24xlarge", "ml.g6.48xlarge", + "ml.g6e.xlarge", + "ml.g6e.2xlarge", + "ml.g6e.4xlarge", + "ml.g6e.8xlarge", + "ml.g6e.12xlarge", + "ml.g6e.16xlarge", + "ml.g6e.24xlarge", + "ml.g6e.48xlarge", ], min_len: None, min_val: None, @@ -21969,6 +22021,58 @@ pub static OPS: &[OpMeta] = &[ "ml.c8g.16xlarge", "ml.c8g.24xlarge", "ml.c8g.48xlarge", + "ml.c6a.large", + "ml.c6a.xlarge", + "ml.c6a.2xlarge", + "ml.c6a.4xlarge", + "ml.c6a.8xlarge", + "ml.c6a.12xlarge", + "ml.c6a.16xlarge", + "ml.c6a.24xlarge", + "ml.c6a.32xlarge", + "ml.c6a.48xlarge", + "ml.m6a.large", + "ml.m6a.xlarge", + "ml.m6a.2xlarge", + "ml.m6a.4xlarge", + "ml.m6a.8xlarge", + "ml.m6a.12xlarge", + "ml.m6a.16xlarge", + "ml.m6a.24xlarge", + "ml.m6a.32xlarge", + "ml.m6a.48xlarge", + "ml.m6g.medium", + "ml.m6g.large", + "ml.m6g.xlarge", + "ml.m6g.2xlarge", + "ml.m6g.4xlarge", + "ml.m6g.8xlarge", + "ml.m6g.12xlarge", + "ml.m6g.16xlarge", + "ml.m7g.medium", + "ml.m7g.large", + "ml.m7g.xlarge", + "ml.m7g.2xlarge", + "ml.m7g.4xlarge", + "ml.m7g.8xlarge", + "ml.m7g.12xlarge", + "ml.m7g.16xlarge", + "ml.m8g.medium", + "ml.m8g.large", + "ml.m8g.xlarge", + "ml.m8g.2xlarge", + "ml.m8g.4xlarge", + "ml.m8g.8xlarge", + "ml.m8g.12xlarge", + "ml.m8g.16xlarge", + "ml.m8g.24xlarge", + "ml.m8g.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -22201,6 +22305,58 @@ pub static OPS: &[OpMeta] = &[ "ml.c8g.16xlarge", "ml.c8g.24xlarge", "ml.c8g.48xlarge", + "ml.c6a.large", + "ml.c6a.xlarge", + "ml.c6a.2xlarge", + "ml.c6a.4xlarge", + "ml.c6a.8xlarge", + "ml.c6a.12xlarge", + "ml.c6a.16xlarge", + "ml.c6a.24xlarge", + "ml.c6a.32xlarge", + "ml.c6a.48xlarge", + "ml.m6a.large", + "ml.m6a.xlarge", + "ml.m6a.2xlarge", + "ml.m6a.4xlarge", + "ml.m6a.8xlarge", + "ml.m6a.12xlarge", + "ml.m6a.16xlarge", + "ml.m6a.24xlarge", + "ml.m6a.32xlarge", + "ml.m6a.48xlarge", + "ml.m6g.medium", + "ml.m6g.large", + "ml.m6g.xlarge", + "ml.m6g.2xlarge", + "ml.m6g.4xlarge", + "ml.m6g.8xlarge", + "ml.m6g.12xlarge", + "ml.m6g.16xlarge", + "ml.m7g.medium", + "ml.m7g.large", + "ml.m7g.xlarge", + "ml.m7g.2xlarge", + "ml.m7g.4xlarge", + "ml.m7g.8xlarge", + "ml.m7g.12xlarge", + "ml.m7g.16xlarge", + "ml.m8g.medium", + "ml.m8g.large", + "ml.m8g.xlarge", + "ml.m8g.2xlarge", + "ml.m8g.4xlarge", + "ml.m8g.8xlarge", + "ml.m8g.12xlarge", + "ml.m8g.16xlarge", + "ml.m8g.24xlarge", + "ml.m8g.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -31285,6 +31441,8 @@ pub static OPS: &[OpMeta] = &[ "Failed", "Deleting", "Updating", + "PendingMaintenance", + "InMaintenance", ], }, Rule { @@ -31568,6 +31726,19 @@ pub static OPS: &[OpMeta] = &[ "ml.trn1.2xlarge", "ml.trn1.32xlarge", "ml.trn1n.32xlarge", + "ml.p6-b200.48xlarge", + "ml.g7e.2xlarge", + "ml.g7e.4xlarge", + "ml.g7e.8xlarge", + "ml.g7e.12xlarge", + "ml.g7e.24xlarge", + "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -31687,6 +31858,19 @@ pub static OPS: &[OpMeta] = &[ "ml.trn1.2xlarge", "ml.trn1.32xlarge", "ml.trn1n.32xlarge", + "ml.p6-b200.48xlarge", + "ml.g7e.2xlarge", + "ml.g7e.4xlarge", + "ml.g7e.8xlarge", + "ml.g7e.12xlarge", + "ml.g7e.24xlarge", + "ml.g7e.48xlarge", + "ml.g7.2xlarge", + "ml.g7.4xlarge", + "ml.g7.8xlarge", + "ml.g7.12xlarge", + "ml.g7.24xlarge", + "ml.g7.48xlarge", ], min_len: None, min_val: None, @@ -38574,6 +38758,12 @@ pub static OPS: &[OpMeta] = &[ "ml.g6.16xlarge", "ml.g6.24xlarge", "ml.g6.48xlarge", + "ml.g7e.2xlarge", + "ml.g7e.4xlarge", + "ml.g7e.8xlarge", + "ml.g7e.12xlarge", + "ml.g7e.24xlarge", + "ml.g7e.48xlarge", "ml.p5.4xlarge", "ml.p5en.48xlarge", "ml.g6e.xlarge", @@ -38750,6 +38940,16 @@ pub static OPS: &[OpMeta] = &[ max_val: None, enums: &[], }, + Rule { + wire: "AuthType", + req: false, + kind: K::Str, + min_len: None, + max_len: None, + min_val: None, + max_val: None, + enums: &["IAM", "IDC"], + }, Rule { wire: "AppVersion", req: false, @@ -39439,6 +39639,7 @@ pub static ACTIONS: &[&str] = &[ "AddAssociation", "AddTags", "AssociateTrialComponent", + "AttachClusterNodeNetworkInterface", "AttachClusterNodeVolume", "BatchAddClusterNodes", "BatchDeleteClusterNodes", diff --git a/crates/fakecloud-sagemaker/src/lib.rs b/crates/fakecloud-sagemaker/src/lib.rs index e95d52665..68bd5c272 100644 --- a/crates/fakecloud-sagemaker/src/lib.rs +++ b/crates/fakecloud-sagemaker/src/lib.rs @@ -1,6 +1,6 @@ //! Amazon SageMaker (`sagemaker`) awsJson1.1 control-plane service for fakecloud. //! -//! The full ~403-operation Amazon SageMaker Smithy model (SDK id `SageMaker`, +//! The full ~404-operation Amazon SageMaker Smithy model (SDK id `SageMaker`, //! SigV4 signing name `sagemaker`, awsJson1.1 protocol). Every request is a //! `POST /` whose operation is selected by the `X-Amz-Target: SageMaker.` //! header, with all inputs carried in the JSON body (no HTTP path / label / diff --git a/crates/fakecloud-sagemaker/src/service.rs b/crates/fakecloud-sagemaker/src/service.rs index 946e1eb30..812754b93 100644 --- a/crates/fakecloud-sagemaker/src/service.rs +++ b/crates/fakecloud-sagemaker/src/service.rs @@ -1,6 +1,6 @@ //! Amazon SageMaker (`sagemaker`) awsJson1.1 dispatch. //! -//! Requests are routed to one of the ~403 modelled operations by the +//! Requests are routed to one of the ~404 modelled operations by the //! `X-Amz-Target: SageMaker.` header (surfaced as //! [`AwsRequest::action`]). All inputs arrive in the JSON body. Input is //! validated against the model-derived constraints ([`crate::validate`]), then diff --git a/crates/fakecloud-sagemaker/src/service/special.rs b/crates/fakecloud-sagemaker/src/service/special.rs index 01822a6bb..4c49b83f3 100644 --- a/crates/fakecloud-sagemaker/src/service/special.rs +++ b/crates/fakecloud-sagemaker/src/service/special.rs @@ -68,6 +68,9 @@ pub(super) fn dispatch( } "ListTrialComponents" => Ok(list_trial_components(svc, ctx, meta, body)), "ListClusterNodes" => Ok(Some(list_cluster_nodes(svc, ctx, meta, body))), + "AttachClusterNodeNetworkInterface" => Ok(Some(attach_cluster_node_network_interface( + svc, ctx, meta, body, + )?)), "ListPipelineExecutionSteps" => Ok(list_pipeline_execution_steps(svc, ctx, meta, body)), "ListPipelineExecutions" => Ok(list_pipeline_executions(svc, ctx, meta, body)), "SendPipelineExecutionStepSuccess" => Ok(Some(send_pipeline_execution_step( @@ -777,6 +780,153 @@ fn list_cluster_nodes( ) } +/// Internal node-record member holding the node's ENI attachments as +/// `{NetworkInterfaceId, AttachmentId}` objects. Not a `ClusterNodeDetails` / +/// `ClusterNodeSummary` field, so every output projection drops it. +const NETWORK_INTERFACE_ATTACHMENTS: &str = "__NetworkInterfaceAttachments"; + +/// `AttachClusterNodeNetworkInterface` — attach an ENI to a node of a HyperPod +/// cluster. The node (matched by logical id or instance id, scoped to the +/// cluster by name or ARN) must exist, else `ResourceNotFound`. The attachment +/// is persisted on the node record: re-attaching the same ENI to the same node +/// returns the existing `AttachmentId`, and an ENI already attached to a +/// different node is rejected with `ConflictException`. +fn attach_cluster_node_network_interface( + svc: &SageMakerService, + ctx: &Ctx, + meta: &OpMeta, + body: &Map, +) -> Result<(AwsResponse, bool), AwsServiceError> { + let cluster = str_member(body, "ClusterName"); + let node_id = str_member(body, "NodeId"); + let eni = str_member(body, "NetworkInterfaceId"); + + let mut g = svc.state.write(); + let data = g.get_or_create(&ctx.account); + + // Nodes carry the `ClusterName` they were added under, which may be the + // cluster's name or its ARN; accept either spelling of a known cluster. + let cluster_record = data + .resolve_key("Cluster", &cluster) + .and_then(|k| data.get_resource("Cluster", &k).cloned()); + // A bare name and this account/region's cluster ARN are interchangeable; an + // ARN from another account or region only ever matches itself. + let local_arn_prefix = super::mint_arn(ctx, "cluster", ""); + let local_name = if cluster.starts_with("arn:") { + cluster.strip_prefix(local_arn_prefix.as_str()) + } else { + Some(cluster.as_str()) + }; + let mut cluster_aliases = vec![cluster.clone()]; + if let Some(name) = local_name.filter(|n| !n.is_empty()) { + cluster_aliases.push(name.to_string()); + cluster_aliases.push(super::mint_arn(ctx, "cluster", name)); + } + if let Some(obj) = cluster_record.as_ref().and_then(Value::as_object) { + for member in ["ClusterName", "ClusterArn"] { + if let Some(v) = obj.get(member).and_then(Value::as_str) { + cluster_aliases.push(v.to_string()); + } + } + } + let cluster_arn = cluster_record + .as_ref() + .and_then(|r| r.get("ClusterArn")) + .and_then(Value::as_str) + .map(str::to_string) + .unwrap_or_else(|| { + if cluster.starts_with("arn:") { + cluster.clone() + } else { + super::mint_arn(ctx, "cluster", &cluster) + } + }); + + let attachments_of = |rec: &Value| -> Vec { + rec.get(NETWORK_INTERFACE_ATTACHMENTS) + .and_then(Value::as_array) + .cloned() + .unwrap_or_default() + }; + let entries = data.list_resource_entries(CLUSTER_NODE_FAMILY); + let Some(node_key) = entries + .iter() + .find(|(_k, rec)| { + cluster_aliases.iter().any(|c| node_in_cluster(rec, c)) && { + let (nlid, iid) = node_identifiers(rec); + Some(node_id.as_str()) == nlid || Some(node_id.as_str()) == iid + } + }) + .map(|(k, _)| k.clone()) + else { + return Err(super::not_found(format!( + "Node '{node_id}' does not exist in cluster '{cluster}'." + ))); + }; + + let mut existing_attachment = None; + for (key, rec) in &entries { + let hit = attachments_of(rec) + .into_iter() + .find(|a| a.get("NetworkInterfaceId").and_then(Value::as_str) == Some(eni.as_str())); + if let Some(a) = hit { + if *key != node_key { + return Err(AwsServiceError::aws_error( + http::StatusCode::CONFLICT, + "ConflictException", + format!("Network interface '{eni}' is already attached to another node."), + )); + } + existing_attachment = a + .get("AttachmentId") + .and_then(Value::as_str) + .map(str::to_string); + } + } + + let mutated = existing_attachment.is_none(); + let attachment_id = match existing_attachment { + Some(id) => id, + None => { + let seq = data.next_seq(); + let seed = super::mint_id( + &ctx.account, + "ClusterNodeNetworkInterface", + &seq.to_string(), + ) + .replace('-', ""); + let attachment_id = format!("eni-attach-{}", &seed[..17]); + if let Some(obj) = data + .get_resource_mut(CLUSTER_NODE_FAMILY, &node_key) + .and_then(Value::as_object_mut) + { + let mut attachments = obj + .get(NETWORK_INTERFACE_ATTACHMENTS) + .and_then(Value::as_array) + .cloned() + .unwrap_or_default(); + attachments.push(serde_json::json!({ + "NetworkInterfaceId": eni, + "AttachmentId": attachment_id, + })); + obj.insert( + NETWORK_INTERFACE_ATTACHMENTS.to_string(), + Value::Array(attachments), + ); + } + attachment_id + } + }; + drop(g); + + let mut out = Map::new(); + out.insert("ClusterArn".to_string(), Value::String(cluster_arn)); + out.insert("NodeId".to_string(), Value::String(node_id)); + out.insert("NetworkInterfaceId".to_string(), Value::String(eni)); + out.insert("AttachmentId".to_string(), Value::String(attachment_id)); + Ok((engine::action(ctx, meta, &out), mutated)) +} + // ── Trial ⇄ trial-component association ─────────────────────────────────── // // `AssociateTrialComponent` / `DisassociateTrialComponent` are Action verbs the diff --git a/crates/fakecloud-sagemaker/src/service/tests.rs b/crates/fakecloud-sagemaker/src/service/tests.rs index 68a657741..3058f031b 100644 --- a/crates/fakecloud-sagemaker/src/service/tests.rs +++ b/crates/fakecloud-sagemaker/src/service/tests.rs @@ -778,6 +778,186 @@ fn batch_cluster_nodes_add_and_delete_round_trip() { assert_eq!(listed["ClusterNodeSummaries"].as_array().unwrap().len(), 1); } +// AttachClusterNodeNetworkInterface persists the attachment on the node: the +// same ENI re-attached to the same node returns the same AttachmentId, an ENI +// already attached elsewhere is a conflict, and an unknown node is not found. +#[test] +fn attach_cluster_node_network_interface_persists_attachment() { + let s = svc(); + let created = resp_json( + &run( + &s, + "CreateCluster", + json!({"ClusterName": "c1", "InstanceGroups": []}), + ) + .unwrap(), + ); + let cluster_arn = created["ClusterArn"].as_str().unwrap().to_string(); + let added = resp_json( + &run( + &s, + "BatchAddClusterNodes", + json!({ + "ClusterName": "c1", + "NodesToAdd": [{"InstanceGroupName": "g1", "IncrementTargetCountBy": 2}], + }), + ) + .unwrap(), + ); + let nodes: Vec = added["Successful"] + .as_array() + .unwrap() + .iter() + .map(|n| n["NodeLogicalId"].as_str().unwrap().to_string()) + .collect(); + + // Attach by cluster ARN; the node was added under the cluster name. + let attached = resp_json( + &run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": cluster_arn, + "NodeId": nodes[0], + "NetworkInterfaceId": "eni-0123456789abcdef0", + }), + ) + .unwrap(), + ); + assert_eq!(attached["ClusterArn"], cluster_arn.as_str()); + assert_eq!(attached["NodeId"], nodes[0].as_str()); + assert_eq!(attached["NetworkInterfaceId"], "eni-0123456789abcdef0"); + let attachment_id = attached["AttachmentId"].as_str().unwrap().to_string(); + assert!(attachment_id.starts_with("eni-attach-"), "{attachment_id}"); + assert_eq!(attachment_id.len(), "eni-attach-".len() + 17); + assert!(attachment_id["eni-attach-".len()..] + .chars() + .all(|c| c.is_ascii_hexdigit() && !c.is_ascii_uppercase())); + + // Re-attaching the same ENI to the same node is idempotent. + let again = resp_json( + &run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": "c1", + "NodeId": nodes[0], + "NetworkInterfaceId": "eni-0123456789abcdef0", + }), + ) + .unwrap(), + ); + assert_eq!(again["AttachmentId"], attachment_id.as_str()); + + // The same ENI cannot also be attached to a second node. + let err = expect_err(run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": "c1", + "NodeId": nodes[1], + "NetworkInterfaceId": "eni-0123456789abcdef0", + }), + )); + assert_eq!(err.code(), "ConflictException"); + + // A different ENI on the second node gets its own attachment id. + let second = resp_json( + &run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": "c1", + "NodeId": nodes[1], + "NetworkInterfaceId": "eni-0fedcba9876543210", + }), + ) + .unwrap(), + ); + assert_ne!(second["AttachmentId"], attachment_id.as_str()); + + // A cluster ARN resolves nodes added under its name even with no stored + // Cluster record. + let added = resp_json( + &run( + &s, + "BatchAddClusterNodes", + json!({"ClusterName": "c2", "NodesToAdd": [{"InstanceGroupName": "g1"}]}), + ) + .unwrap(), + ); + let c2_node = added["Successful"][0]["NodeLogicalId"].as_str().unwrap(); + let by_arn = resp_json( + &run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": "arn:aws:sagemaker:us-east-1:000000000000:cluster/c2", + "NodeId": c2_node, + "NetworkInterfaceId": "eni-0bbbbbbbbbbbbbbbb", + }), + ) + .unwrap(), + ); + assert_eq!( + by_arn["ClusterArn"], + "arn:aws:sagemaker:us-east-1:000000000000:cluster/c2" + ); + + // And the reverse: nodes added under the ARN resolve by the bare name. + let added = resp_json( + &run( + &s, + "BatchAddClusterNodes", + json!({ + "ClusterName": "arn:aws:sagemaker:us-east-1:000000000000:cluster/c3", + "NodesToAdd": [{"InstanceGroupName": "g1"}], + }), + ) + .unwrap(), + ); + let c3_node = added["Successful"][0]["NodeLogicalId"] + .as_str() + .unwrap() + .to_string(); + run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": "c3", + "NodeId": c3_node, + "NetworkInterfaceId": "eni-0cccccccccccccccc", + }), + ) + .unwrap(); + + // A same-named cluster ARN from another account does not reach local nodes. + let err = expect_err(run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": "arn:aws:sagemaker:eu-west-1:111111111111:cluster/c2", + "NodeId": c2_node, + "NetworkInterfaceId": "eni-0dddddddddddddddd", + }), + )); + assert_eq!(err.code(), "ResourceNotFound"); + + // Unknown node, and a known node addressed through the wrong cluster. + for (cluster, node) in [("c1", "i-00000000000000999"), ("other", nodes[0].as_str())] { + let err = expect_err(run( + &s, + "AttachClusterNodeNetworkInterface", + json!({ + "ClusterName": cluster, + "NodeId": node, + "NetworkInterfaceId": "eni-0aaaaaaaaaaaaaaaa", + }), + )); + assert_eq!(err.code(), "ResourceNotFound"); + } +} + // BatchRebootClusterNodes reports in Successful exactly the requested ids that // resolve to a node in the cluster (reading real persisted state). #[test] diff --git a/scripts/generate-sagemaker-tables.py b/scripts/generate-sagemaker-tables.py index 8a3232a1b..e3bc29421 100644 --- a/scripts/generate-sagemaker-tables.py +++ b/scripts/generate-sagemaker-tables.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Regenerate crates/fakecloud-sagemaker/src/generated.rs from aws-models/sagemaker.json. -Amazon SageMaker is an awsJson1.1 service with ~403 operations; hand-maintaining +Amazon SageMaker is an awsJson1.1 service with ~404 operations; hand-maintaining the operation table, per-operation input constraints, output member shapes, list element shapes, resource families and identifier members would be error-prone, so they are generated directly from the Smithy model. Unlike the restJson1 IoT crate, diff --git a/website/content/docs/about/conformance.md b/website/content/docs/about/conformance.md index 43e158531..57366b541 100644 --- a/website/content/docs/about/conformance.md +++ b/website/content/docs/about/conformance.md @@ -35,7 +35,7 @@ Every response is validated against the operation's Smithy output shape. Missing ## Current coverage -248,557/248,557 generated test variants across all 105 services (7,505 operations) pass on every commit — true 100% conformance with no flake margin and no skipped services. The exact pass/total per service is checked into [`conformance-baseline.json`](https://github.com/faiscadev/fakecloud/blob/main/conformance-baseline.json). +248,557/248,557 generated test variants across all 105 services (7,506 operations) pass on every commit — true 100% conformance with no flake margin and no skipped services. The exact pass/total per service is checked into [`conformance-baseline.json`](https://github.com/faiscadev/fakecloud/blob/main/conformance-baseline.json). See the harness and methodology at [`crates/fakecloud-conformance/`](https://github.com/faiscadev/fakecloud/tree/main/crates/fakecloud-conformance). diff --git a/website/content/docs/migration-from-localstack.md b/website/content/docs/migration-from-localstack.md index e99c5e164..6100d66ed 100644 --- a/website/content/docs/migration-from-localstack.md +++ b/website/content/docs/migration-from-localstack.md @@ -9,7 +9,7 @@ If your local development workflow is blocked by LocalStack's account requiremen ## Key Differences - **No API Key**: fakecloud is fully functional offline. No `ACTIVATE_PRO` or account login required. - **Single Binary**: Replace heavy Docker-in-Docker setups with a ~19MB binary that starts in <300ms. -- **Parity**: 100% API conformance across 7,505 operations, including features LocalStack gates behind Pro (like ECR and Bedrock). +- **Parity**: 100% API conformance across 7,506 operations, including features LocalStack gates behind Pro (like ECR and Bedrock). ## Service Mapping | Feature | LocalStack | fakecloud | diff --git a/website/content/docs/operations/_index.md b/website/content/docs/operations/_index.md index d4e0b68ce..f6c6d7ff8 100644 --- a/website/content/docs/operations/_index.md +++ b/website/content/docs/operations/_index.md @@ -3255,6 +3255,7 @@ This is a surface listing, not an implementation manifest. For fakecloud's per-s - `AddAssociation` - `AddTags` - `AssociateTrialComponent` +- `AttachClusterNodeNetworkInterface` - `AttachClusterNodeVolume` - `BatchAddClusterNodes` - `BatchDeleteClusterNodes` diff --git a/website/content/docs/parity.md b/website/content/docs/parity.md index e706482c0..f042bd9b1 100644 --- a/website/content/docs/parity.md +++ b/website/content/docs/parity.md @@ -4,7 +4,7 @@ description = "Service-by-service behavior parity: what is real, what is synthes weight = 1 +++ -fakecloud implements **105 AWS services** with **7,505 operations**. **248,557/248,557 generated Smithy conformance variants pass** on every commit — true 100% across every implemented service, no flake margin and no skipped services. Conformance checks request/response shapes, field names, and error codes against [AWS's own Smithy models](https://github.com/faiscadev/fakecloud/blob/main/conformance-baseline.json). Behavior parity varies by service — some run real infrastructure (Postgres, Redis, Docker containers), some run a real control plane but return synthesized data for complex queries, and a few have control-plane-only coverage with no data-plane enforcement. +fakecloud implements **105 AWS services** with **7,506 operations**. **248,557/248,557 generated Smithy conformance variants pass** on every commit — true 100% across every implemented service, no flake margin and no skipped services. Conformance checks request/response shapes, field names, and error codes against [AWS's own Smithy models](https://github.com/faiscadev/fakecloud/blob/main/conformance-baseline.json). Behavior parity varies by service — some run real infrastructure (Postgres, Redis, Docker containers), some run a real control plane but return synthesized data for complex queries, and a few have control-plane-only coverage with no data-plane enforcement. | Service | Ops | Protocol | Control plane | Data plane | Known limitations | | --- | --- | --- | --- | --- | --- | @@ -38,7 +38,7 @@ fakecloud implements **105 AWS services** with **7,505 operations**. **248,557/2 | [Amazon Pinpoint](@/docs/services/pinpoint.md) | 122 | REST-JSON | Full | Control plane | Complete 122-op Amazon Pinpoint control plane (signs as `mobiletargeting`, routed by HTTP method + `@http` URI path under `/v1`): apps (`CreateApp` mints a 32-hex id + `arn:aws:mobiletargeting:::apps/` ARN; `GetApp`/`GetApps`/`DeleteApp`; `Get`/`UpdateApplicationSettings`); versioned campaigns + segments (each `Update` bumps `Version` and is listed by `GetCampaignVersions`/`GetSegmentVersions` + the by-version reads; `CreateSegment` derives `SegmentType` `IMPORT`-vs-`DIMENSIONAL`; `GetCampaignActivities`/`GetSegment{Import,Export}Jobs`); endpoints + users (per-`(appId,endpointId)` storage, `UpdateEndpointsBatch`, `Get`/`DeleteUserEndpoints` over a shared `User.UserId`, `RemoveAttributes`); all platform channels (ADM, APNS + sandbox/VoIP/VoIP-sandbox, Baidu, Email, GCM, SMS, Voice — `Get`/`Update`/`Delete` echoing `Platform` + `Enabled`, plus `GetChannels`); journeys (`DRAFT` -> `ACTIVE` state machine via `UpdateJourneyState`, `GetJourneyRuns`); email/push/sms/voice/inapp templates (versioned, `UpdateTemplateActiveVersion`, `ListTemplates`/`ListTemplateVersions`); import/export jobs (mint a `JobId`, settle to `COMPLETED`); event streams (`Put`/`Get`/`DeleteEventStream`); recommender configurations; and ARN-keyed tags. Model-derived required/label validation with Pinpoint's declared exceptions (`BadRequestException`/`NotFoundException`/`ConflictException`/`ForbiddenException`/`TooManyRequestsException`/`PayloadTooLargeException`/`MethodNotAllowedException`/`InternalServerErrorException`); account-partitioned and persisted. Honest gaps: no real delivery (`SendMessages`/`SendUsersMessages`/`SendOTPMessage`/`PutEvents`/`VerifyOTPMessage` validate + return a structurally-correct `MessageResponse` with a per-address delivery status but transmit nothing), the KPI / execution-metric reads return empty/zeroed metric result sets (no analytics engine), and import/export jobs do not read or write S3. | | [AWS IoT Core](@/docs/services/iot.md) | 272 | REST-JSON | Full | Registry/jobs/rules/security control plane | Full 272-op AWS IoT Core control plane, signed as `iot` and routed by HTTP method plus `@http` URI path. The route table, per-operation HTTP bindings, model-derived input constraints, and output member shapes are all generated from AWS's Smithy model. Every modelled resource family mints proper ARNs + ids, persists its attributes, and round-trips on read/list with paginating `nextToken`s: things / thing types / thing groups (static + dynamic) / billing groups (with membership via `AddThingToThingGroup` / `AddThingToBillingGroup`), policies (+ versions + default version + v2 `AttachPolicy`/`ListAttachedPolicies`/`ListTargetsForPolicy` and legacy `AttachPrincipalPolicy`/`ListPrincipalPolicies` attachments), certificates (`CreateKeysAndCertificate`/`CreateCertificateFromCsr` mint a 64-hex id + ARN + structurally-shaped PEM + RSA key pair; `RegisterCertificate`/`RegisterCACertificate`; `AttachThingPrincipal`/`ListThingPrincipals`), jobs + job templates, topic rules + destinations (SQL + actions stored verbatim; `Enable`/`Disable` flip the disabled flag), Device Defender (security profiles, scheduled audits, account audit configuration, mitigation actions, custom metrics, dimensions), provisioning templates (+ versions), domain configurations, fleet metrics, role aliases, authorizers (+ default authorizer), streams, OTA updates, packages (+ versions), certificate providers, commands, `DescribeEndpoint` (deterministic per-account host per endpoint type), and ARN-keyed tagging. Model-derived `required`/`length`/`range`/`enum` validation with each op's declared exceptions (`ResourceNotFoundException`/`InvalidRequestException`/`ResourceAlreadyExistsException`/`VersionConflictException`/`DeleteConflictException`/...). Account-partitioned and persisted. Honest gaps: no live MQTT broker or device connectivity -- the control plane is real but no message is routed, no topic-rule action executes against a real target, and no device attaches over MQTT (the device data plane lives in the separate `iotdata` service); `SearchIndex` + aggregation ops run against the in-memory thing registry with a bounded query subset (`*`, `thingName:`, bare name), returning `InvalidQueryException` for anything else rather than a wrong result; certificates are structurally-valid PEM placeholders, not real CA-signed X.509 chains. | | [AWS IoT Wireless](@/docs/services/iotwireless.md) | 112 | REST-JSON | Full | LoRaWAN/Sidewalk registry control plane | Full 112-op AWS IoT Wireless control plane, signed as `iotwireless` and routed by HTTP method plus `@http` URI path. The route table, per-operation HTTP bindings, model-derived input constraints, and output member shapes are all generated from AWS's Smithy model. Unlike AWS IoT Core, IoT Wireless models every create as a collection `POST` with the new resource's identifier in the response, so families whose create output carries an `Id` mint a UUID-shaped id (device profiles, service profiles, FUOTA tasks, multicast groups, wireless devices, wireless gateways, task definitions) while the two name-addressed families (destinations, network-analyzer configurations) key off the required body `Name`. Every named resource mints proper ARNs + ids, persists its attributes, and round-trips on read/list/update with paginating `NextToken`s: destinations, device/service profiles, FUOTA tasks, multicast groups, wireless devices + gateways, network-analyzer configurations, wireless-gateway task definitions, position configurations (`Put`/`Get`), and resource positions (raw GeoJSON `@httpPayload` blob). ARN-keyed tagging (`TagResource`/`ListTagsForResource`/`UntagResource`). Model-derived `required`/`length`/`range`/`enum` validation (including required `@httpPayload`) with each op's declared exceptions (`ValidationException`/`ResourceNotFoundException`/`ConflictException`/...). Account-partitioned and persisted. Honest gaps: no live LoRaWAN/Sidewalk radio plane -- the control plane is real but no device transmits, no downlink is delivered (`SendDataToWirelessDevice`/`SendDataToMulticastGroup`), no FUOTA image is fragmented, and no gateway task runs; association/session operations are accepted (and persisted where addressed by a stored resource) but drive no radio behaviour. | -| [Amazon SageMaker](@/docs/services/sagemaker.md) | 403 | JSON 1.1 | Full | Control-plane only | Full 403-op Amazon SageMaker control plane, signed as `sagemaker` and routed by the `X-Amz-Target: SageMaker.` header (awsJson1.1, all inputs in the JSON body). The operation table, model-derived input constraints, output member shapes, list element shapes, and each op's resource family + identifier member are all generated from AWS's Smithy model (`scripts/generate-sagemaker-tables.py`). A single uniform engine serves all ~130 resource families: `Create` mints an `arn:aws:sagemaker:...:/` ARN + numeric `CreationTime`/`LastModifiedTime`, persists every accepted input field and returns `Arn`; `Describe` echoes the persisted record; `Lists` projects each record onto its `Summary` with paginating `NextToken`s; `Update` merges + refreshes `LastModifiedTime`; `Delete` is idempotent. Covers models, endpoint configs, endpoints, training/processing/transform/labeling/compilation/AutoML(v1+v2)/hyper-parameter-tuning jobs, model packages (+ groups), pipelines, feature groups, domains, user profiles, spaces, apps, images (+ versions), experiments, trials (+ components), actions, artifacts, contexts, clusters, inference components, monitoring schedules, notebook instances (+ lifecycle configs), code repositories, workteams, and workforces. ARN-keyed tagging (`AddTags`/`ListTags`/`DeleteTags`). Model-derived `required`/`length`/`range`/`enum` validation returning SageMaker's `ValidationException`; missing resource -> `ResourceNotFound`, duplicate create -> `ResourceInUse`. Account-partitioned and persisted. Honest gaps: control plane only -- there is no ML execution plane; training/processing/transform/AutoML/tuning jobs are created, persisted, and described but no container is scheduled, no model is trained, and no inference endpoint serves traffic; jobs and endpoints are not advanced through a live lifecycle by a background scheduler; presigned-URL and lineage/search query operations are accepted as control-plane no-ops. | +| [Amazon SageMaker](@/docs/services/sagemaker.md) | 404 | JSON 1.1 | Full | Control-plane only | Full 404-op Amazon SageMaker control plane, signed as `sagemaker` and routed by the `X-Amz-Target: SageMaker.` header (awsJson1.1, all inputs in the JSON body). The operation table, model-derived input constraints, output member shapes, list element shapes, and each op's resource family + identifier member are all generated from AWS's Smithy model (`scripts/generate-sagemaker-tables.py`). A single uniform engine serves all ~130 resource families: `Create` mints an `arn:aws:sagemaker:...:/` ARN + numeric `CreationTime`/`LastModifiedTime`, persists every accepted input field and returns `Arn`; `Describe` echoes the persisted record; `Lists` projects each record onto its `Summary` with paginating `NextToken`s; `Update` merges + refreshes `LastModifiedTime`; `Delete` is idempotent. Covers models, endpoint configs, endpoints, training/processing/transform/labeling/compilation/AutoML(v1+v2)/hyper-parameter-tuning jobs, model packages (+ groups), pipelines, feature groups, domains, user profiles, spaces, apps, images (+ versions), experiments, trials (+ components), actions, artifacts, contexts, clusters, inference components, monitoring schedules, notebook instances (+ lifecycle configs), code repositories, workteams, and workforces. ARN-keyed tagging (`AddTags`/`ListTags`/`DeleteTags`). Model-derived `required`/`length`/`range`/`enum` validation returning SageMaker's `ValidationException`; missing resource -> `ResourceNotFound`, duplicate create -> `ResourceInUse`. Account-partitioned and persisted. Honest gaps: control plane only -- there is no ML execution plane; training/processing/transform/AutoML/tuning jobs are created, persisted, and described but no container is scheduled, no model is trained, and no inference endpoint serves traffic; jobs and endpoints are not advanced through a live lifecycle by a background scheduler; presigned-URL and lineage/search query operations are accepted as control-plane no-ops. | | [Resource Groups](@/docs/services/resource-groups.md) | 23 | REST-JSON | Full | Partial | Full 23-op control plane: group lifecycle (Create/Get/Update/Delete/ListGroups), resource queries (`TAG_FILTERS_1_0` / `CLOUDFORMATION_STACK_1_0`) via GetGroupQuery/UpdateGroupQuery, explicit membership (GroupResources/UngroupResources/ListGroupResources), group configuration, tagging (Tag/Untag/GetTags), account settings, grouping statuses, and tag-sync tasks. `arn:aws:resource-groups:...:group//` ARNs, account-partitioned and persisted. Query-based membership resolution (evaluating a tag/CloudFormation-stack query against live resources) depends on the cross-service tag index shipping with the Resource Groups Tagging API; explicit membership is fully real now. | | [Resource Groups Tagging API](@/docs/services/resource-groups-tagging.md) | 9 | JSON 1.1 | Full | Partial | All 9 ops: `GetResources` (with `ResourceARNList` / `ResourceTypeFilters` / `TagFilters` and pagination), `GetTagKeys`, `GetTagValues`, `TagResources`, `UntagResources`, `GetComplianceSummary`, `StartReportCreation`, `DescribeReportCreation`, `ListRequiredTags`. Backed by a cross-service tag index: reads aggregate every service's live tags through a shared provider registry, plus tags applied directly to arbitrary ARNs via `TagResources`. Account-partitioned and persisted. Per-service tag providers roll out incrementally; today the index reflects tags applied through this API. | | [Resource Access Manager](@/docs/services/ram.md) | 35 | REST-JSON | Full | None | Complete 35-op RAM surface: resource shares (create with resource ARNs / principals / permissions at creation, get/update/delete, `GetResourceShares` with `SELF` / `OTHER-ACCOUNTS` resourceOwner filter), resource + principal associations (`AssociateResourceShare` / `DisassociateResourceShare` settle straight to `ASSOCIATED`, `GetResourceShareAssociations`), cross-account share invitations (`Accept`/`Reject`/`GetResourceShareInvitations`, external principals raise a `PENDING` invitation), managed + customer permissions with the full version lifecycle (`CreatePermission`/`CreatePermissionVersion`/`ListPermissionVersions`/`SetDefaultPermissionVersion`/`DeletePermissionVersion`, `AssociateResourceSharePermission`/`ReplacePermissionAssociations`), a seeded AWS-managed default-permission catalogue (`AWSRAMDefaultPermission*`), `ListResourceTypes`/`ListPrincipals`/`ListResources`, `EnableSharingWithAwsOrganization`, promote-from-policy, and tagging. Model-derived `@length`/`@range`/enum validation. Account-partitioned and persisted. | diff --git a/website/content/docs/services/sagemaker.md b/website/content/docs/services/sagemaker.md index 1d40763bf..bfb09d904 100644 --- a/website/content/docs/services/sagemaker.md +++ b/website/content/docs/services/sagemaker.md @@ -1,12 +1,12 @@ +++ title = "Amazon SageMaker" -description = "Amazon SageMaker (sagemaker) on fakecloud: the full 403-operation ML control plane — models, endpoints, endpoint configs, training/processing/transform/AutoML/tuning jobs, notebook instances, pipelines, feature groups, domains, model packages — at 100% conformance. awsJson1.1." +description = "Amazon SageMaker (sagemaker) on fakecloud: the full 404-operation ML control plane — models, endpoints, endpoint configs, training/processing/transform/AutoML/tuning jobs, notebook instances, pipelines, feature groups, domains, model packages — at 100% conformance. awsJson1.1." weight = 80 +++ fakecloud implements the **Amazon SageMaker control plane** (`sagemaker`, SDK id `SageMaker`, endpoint prefix `api.sagemaker`) as an **awsJson1.1** service. All -**403 operations** ship with **100% conformance** against AWS's own Smithy +**404 operations** ship with **100% conformance** against AWS's own Smithy model, backed by account-partitioned state that persists across restarts in persistent mode. SageMaker signs SigV4 with the `sagemaker` scope; every request is a `POST /` whose operation is selected by the `X-Amz-Target: SageMaker.` @@ -63,6 +63,13 @@ round-trips on read / list / update: schedules**, **notebook instances** (+ lifecycle configs), **code repositories**, **workteams**, **workforces**, and the rest of the ~130 families. +- **HyperPod cluster nodes** — `BatchAddClusterNodes` persists nodes that + `ListClusterNodes` reflects; `BatchReplaceClusterNodes` / + `BatchDeleteClusterNodes` mutate them. `AttachClusterNodeNetworkInterface` + records an `eni-attach-*` attachment on an existing node (re-attaching the + same ENI to the same node returns the same attachment; an ENI already on + another node is a `ConflictException`; an unknown node is + `ResourceNotFound`). - **Tags** — ARN-keyed `AddTags` / `ListTags` / `DeleteTags`. Input validation is model-derived: `required` members, string `@length`, diff --git a/website/content/fake-aws-server.md b/website/content/fake-aws-server.md index 3d4d1ffed..6b9eba896 100644 --- a/website/content/fake-aws-server.md +++ b/website/content/fake-aws-server.md @@ -16,7 +16,7 @@ Listens on `http://localhost:4566`. Any AWS SDK in any language points at it and ## What "fake AWS server" means here - **Real HTTP server**, not an in-process mock. Your Go / Java / Kotlin / Node / Rust / PHP / Python code uses the regular AWS SDK with `endpoint_url` set to `http://localhost:4566`. -- **Speaks the AWS wire protocol** at true 100% conformance across every implemented service. 105 services, 7,505 operations, 248,557/248,557 Smithy-model-generated test variants pass on every commit. +- **Speaks the AWS wire protocol** at true 100% conformance across every implemented service. 105 services, 7,506 operations, 248,557/248,557 Smithy-model-generated test variants pass on every commit. - **Real execution** for stateful services: Lambda runs your function code in Docker containers across 23 runtimes, RDS runs real PostgreSQL/MySQL/MariaDB/Oracle/SQL Server/Db2, ElastiCache runs real Redis/Valkey/Memcached. - **Real cross-service wiring**: S3 -> Lambda, SQS -> Lambda, SNS fan-out, EventBridge -> Step Functions, and 15+ more integrations execute end-to-end, not as stubs. - **Free, open-source, AGPL-3.0.** No account, no auth token, no paid tier. diff --git a/website/content/faq.md b/website/content/faq.md index 9f4922df2..f61b4bf90 100644 --- a/website/content/faq.md +++ b/website/content/faq.md @@ -20,7 +20,7 @@ Yes. LocalStack replaced its open-source Community Edition with a proprietary im ### How many AWS services does fakecloud support? -105 services and 7,505 API operations. 248,557/248,557 generated Smithy conformance variants pass on every commit — true 100% across every implemented service, with more services on the roadmap. The explicit goal is 100% of AWS services, each at 100% behavioral conformance, with 100% of cross-service integrations. Services land depth-first — a service is added when it passes the full Smithy-model test variants and cross-service wire-ups. +105 services and 7,506 API operations. 248,557/248,557 generated Smithy conformance variants pass on every commit — true 100% across every implemented service, with more services on the roadmap. The explicit goal is 100% of AWS services, each at 100% behavioral conformance, with 100% of cross-service integrations. Services land depth-first — a service is added when it passes the full Smithy-model test variants and cross-service wire-ups. ### Which AWS services are supported? @@ -109,7 +109,7 @@ GitHub issues: [github.com/faiscadev/fakecloud/issues](https://github.com/faisca {"@type": "Question", "name": "What is fakecloud?", "acceptedAnswer": {"@type": "Answer", "text": "fakecloud is a free, open-source local AWS cloud emulator for integration testing and local development. It runs on a single port (4566), requires no account or auth token, and aims for 100% behavioral conformance with real AWS on every service it implements. AGPL-3.0 licensed."}}, {"@type": "Question", "name": "Is fakecloud free?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. AGPL-3.0, free for commercial use. Using fakecloud as a dev/test dependency has zero AGPL implications for your application."}}, {"@type": "Question", "name": "Is fakecloud a LocalStack alternative?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. LocalStack replaced its open-source Community Edition with a proprietary image in March 2026 that requires an account and auth token. fakecloud is a free, open-source replacement."}}, - {"@type": "Question", "name": "How many AWS services does fakecloud support?", "acceptedAnswer": {"@type": "Answer", "text": "105 services and 7,505 API operations. 248,557/248,557 generated Smithy conformance variants pass on every commit, true 100% across every implemented service, with more on the roadmap. The goal is 100% of AWS services, each at 100% behavioral conformance, with 100% of cross-service integrations."}}, + {"@type": "Question", "name": "How many AWS services does fakecloud support?", "acceptedAnswer": {"@type": "Answer", "text": "105 services and 7,506 API operations. 248,557/248,557 generated Smithy conformance variants pass on every commit, true 100% across every implemented service, with more on the roadmap. The goal is 100% of AWS services, each at 100% behavioral conformance, with 100% of cross-service integrations."}}, {"@type": "Question", "name": "Which AWS services are supported?", "acceptedAnswer": {"@type": "Answer", "text": "S3, SQS, SNS, EventBridge, EventBridge Pipes, EventBridge Scheduler, Lambda, EC2, DynamoDB, IAM, STS, Organizations, SSM, Secrets Manager, CloudWatch Logs, CloudWatch (Metrics & Alarms), KMS, CloudFormation, Cloud Control API, SES (v2 + v1 inbound), Cognito User Pools, Cognito Identity, Kinesis, Firehose, RDS, RDS Data API, Aurora DSQL, Resource Groups, Resource Groups Tagging API, ElastiCache, Step Functions, API Gateway v1 (REST), API Gateway v2 (HTTP), Bedrock, Bedrock Agent, Bedrock Agent Runtime, Bedrock Runtime, ECR, ECS, Elastic Load Balancing v2, CloudFront, Route 53, WAF v2, Application Auto Scaling, Athena, ACM, Glue."}}, {"@type": "Question", "name": "Does fakecloud execute Lambda code for real?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. fakecloud pulls real AWS Lambda runtime containers and executes your handler against them. 27 official runtimes including Node.js 16/18/20/22/24, Python 3.8 through 3.14, Java 11/17/21/25, .NET 6/8/10, Ruby 3.2, Go (go1.x), and custom provided/provided.al2/provided.al2023."}}, {"@type": "Question", "name": "Does fakecloud run real databases for RDS?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. RDS emulation pulls real PostgreSQL, MySQL, MariaDB, Oracle, SQL Server, and Db2 Docker images and runs them as the DB instance."}}, diff --git a/website/content/localstack-alternative.md b/website/content/localstack-alternative.md index d074f0f7d..b30c97a39 100644 --- a/website/content/localstack-alternative.md +++ b/website/content/localstack-alternative.md @@ -1,6 +1,6 @@ +++ title = "Free, open-source LocalStack alternative" -description = "fakecloud is a free, open-source local AWS emulator: 105 services, 7,505 operations, 248,557/248,557 Smithy variants pass (true 100% conformance), 6 test-assertion SDKs. No account, no token, no paid tier. Drop-in replacement for LocalStack Community." +description = "fakecloud is a free, open-source local AWS emulator: 105 services, 7,506 operations, 248,557/248,557 Smithy variants pass (true 100% conformance), 6 test-assertion SDKs. No account, no token, no paid tier. Drop-in replacement for LocalStack Community." template = "page.html" aliases = [ "/alternative/localstack/", @@ -31,7 +31,7 @@ This is why fakecloud runs real Lambda code in real runtime containers, runs rea ## What fakecloud gives you - **105 AWS services.** S3, SQS, SNS, EventBridge, EventBridge Pipes, EventBridge Scheduler, Lambda, EC2, DynamoDB, IAM, STS, Organizations, SSM, Secrets Manager, CloudWatch Logs, CloudWatch (Metrics & Alarms), KMS, CloudFormation, Cloud Control API, SES (v2 + v1 inbound), Cognito User Pools, Cognito Identity, Kinesis, Firehose, RDS, RDS Data API, Aurora DSQL, Resource Groups, Resource Groups Tagging API, ElastiCache, Step Functions, API Gateway v1 (REST), API Gateway v2 (HTTP), Bedrock, Bedrock Agent, Bedrock Agent Runtime, Bedrock Runtime, ECR, ECS, Elastic Load Balancing v2, CloudFront, Route 53, WAF v2, Application Auto Scaling, Athena, ACM, Glue. -- **7,505 API operations. True 100% conformance** across every implemented service — 248,557/248,557 Smithy-model-generated test variants pass on every commit. +- **7,506 API operations. True 100% conformance** across every implemented service — 248,557/248,557 Smithy-model-generated test variants pass on every commit. - **Tested against upstream Terraform acceptance tests.** CI runs `hashicorp/terraform-provider-aws` `TestAcc*` suites against fakecloud, catching waiter and field-presence drift that pure SDK tests miss. - **Real Lambda execution.** 23 runtimes in Docker containers. Not a mock, not a stub. Node, Python, Java, Go, .NET, Ruby, custom runtimes. - **Real stateful services.** RDS runs real PostgreSQL/MySQL/MariaDB/Oracle/SQL Server/Db2. ElastiCache runs real Redis/Valkey/Memcached. Your Lambda talking to RDS is talking to a real Postgres (or Oracle, or SQL Server). diff --git a/website/content/supported-services.md b/website/content/supported-services.md index 61ea031c8..753490609 100644 --- a/website/content/supported-services.md +++ b/website/content/supported-services.md @@ -1,14 +1,14 @@ +++ title = "AWS Service Coverage & API Conformance" -description = "fakecloud provides 100% API conformance across 7,505 operations. Explore our supported AWS services for local development." +description = "fakecloud provides 100% API conformance across 7,506 operations. Explore our supported AWS services for local development." template = "page.html" +++ -fakecloud provides 100% API conformance across 7,505 operations. Unlike mocks, fakecloud is built against official AWS Smithy models to ensure wire-protocol compatibility and deterministic behavior for local development. +fakecloud provides 100% API conformance across 7,506 operations. Unlike mocks, fakecloud is built against official AWS Smithy models to ensure wire-protocol compatibility and deterministic behavior for local development. ## Coverage Summary - **Total Services**: 105 -- **Total Operations**: 7,505 +- **Total Operations**: 7,506 - **Conformance Engine**: 248,557 Smithy-based test variants - **Startup Time**: ~300ms diff --git a/website/static/llms-full.txt b/website/static/llms-full.txt index dd4b80362..11bc396be 100644 --- a/website/static/llms-full.txt +++ b/website/static/llms-full.txt @@ -6,7 +6,7 @@ fakecloud emulates AWS locally for integration testing and development. It is a single Rust binary (~19 MB, ~300ms startup, ~10 MiB idle memory) — no Docker required to run fakecloud itself, no signup. Point any AWS SDK or the AWS CLI at `http://localhost:4566` with dummy credentials. -**Coverage goal:** 100% of AWS services, each at 100% behavioral conformance, with 100% of cross-service integrations. Approach is depth-first — a service lands when it passes the full Smithy-model test variants and the cross-service wire-ups that matter for it, not when the API surface looks filled in. 105 services (7,505 operations) are shipped today, all at true 100% conformance — 248,557/248,557 generated Smithy variants pass on every commit; more land progressively as they hit the bar. +**Coverage goal:** 100% of AWS services, each at 100% behavioral conformance, with 100% of cross-service integrations. Approach is depth-first — a service lands when it passes the full Smithy-model test variants and the cross-service wire-ups that matter for it, not when the API surface looks filled in. 105 services (7,506 operations) are shipped today, all at true 100% conformance — 248,557/248,557 generated Smithy variants pass on every commit; more land progressively as they hit the bar. Key design principles: - **Depth-first coverage**: every implemented service targets 100% conformance with real AWS, validated on every commit against AWS's own Smithy models — 248,557/248,557 generated test variants pass on every commit, true 100% across every implemented service. CI also runs upstream `hashicorp/terraform-provider-aws` `TestAcc*` suites against fakecloud. diff --git a/website/static/llms.txt b/website/static/llms.txt index 61e73eab3..74e4a2040 100644 --- a/website/static/llms.txt +++ b/website/static/llms.txt @@ -4,7 +4,7 @@ - **Goal:** 100% of AWS services, each at 100% conformance, with 100% of cross-service integrations. Approach is depth-first — a service is added when it passes the full Smithy-model test variants and cross-service wire-ups, not when the API surface looks filled in. - Single static binary (~19 MB), ~300ms startup, ~10 MiB idle memory, no Docker required to run fakecloud itself -- **105 AWS services shipped today, 7,505 operations, true 100% Smithy conformance — 248,557/248,557 generated test variants pass on every commit**, no flake margin and no skipped services. More services land as they hit the conformance bar; roadmap is driven by real-project demand. +- **105 AWS services shipped today, 7,506 operations, true 100% Smithy conformance — 248,557/248,557 generated test variants pass on every commit**, no flake margin and no skipped services. More services land as they hit the conformance bar; roadmap is driven by real-project demand. - Services: S3, SQS, SNS, EventBridge, EventBridge Pipes, EventBridge Scheduler, Lambda, EC2, DynamoDB, IAM, STS, Organizations, SSM, Secrets Manager, CloudWatch Logs, CloudWatch (Metrics & Alarms), KMS, CloudFormation, Cloud Control API, SES (v2 + v1 inbound), Cognito User Pools, Cognito Identity, Kinesis, Firehose, RDS, RDS Data API, Aurora DSQL, Resource Groups, Resource Groups Tagging API, ElastiCache, MemoryDB, EKS, AWS Backup, AWS AppConfig, Cloud Map, Step Functions, API Gateway v1 (REST), API Gateway v2 (HTTP), Bedrock, Bedrock Agent, Bedrock Agent Runtime, Bedrock Runtime, ECR, ECS, Elastic Load Balancing v2, CloudFront, CloudTrail, Route 53, WAF v2, Application Auto Scaling, Athena, ACM, Glue - 30+ cross-service integrations: S3 notifications, SNS fan-out, EventBridge rules, DynamoDB Streams, CloudWatch Logs subscriptions, Cognito triggers, API Gateway -> Lambda, Step Functions task integrations, SES inbound -> S3/SNS/Lambda, and more - Real Lambda execution via Docker across 23 runtimes (Node.js 16/18/20/22/24, Python 3.8/3.9/3.10/3.11/3.12/3.13/3.14, Java 11/17/21/25, Go 1.x, Ruby 3.3/3.4, .NET 8/10, custom `provided.al2` / `provided.al2023`) diff --git a/website/templates/index.html b/website/templates/index.html index f5fbd8370..93cc65c12 100644 --- a/website/templates/index.html +++ b/website/templates/index.html @@ -12,7 +12,7 @@ "applicationCategory": "DeveloperApplication", "applicationSubCategory": "CloudTestingTool", "operatingSystem": "Linux, macOS, Windows", - "description": "Free, open-source local AWS cloud emulator. 105 services, 7,505 operations, 248,557/248,557 Smithy variants pass — true 100% conformance. Single binary, no account, no auth token.", + "description": "Free, open-source local AWS cloud emulator. 105 services, 7,506 operations, 248,557/248,557 Smithy variants pass — true 100% conformance. Single binary, no account, no auth token.", "url": "https://fakecloud.dev", "downloadUrl": "https://github.com/faiscadev/fakecloud/releases", "codeRepository": "https://github.com/faiscadev/fakecloud", @@ -56,7 +56,7 @@

fakecloud

Local AWS cloud emulator for integration tests. Run your app with normal AWS clients, stay fully local, and use fakecloud SDKs when your tests need deeper visibility.

-

105 services. 7,505 operations. 248,557/248,557 Smithy variants pass — true 100% conformance.

+

105 services. 7,506 operations. 248,557/248,557 Smithy variants pass — true 100% conformance.